Sahi + Sikuli = Sakuli

Sakuli: End-2-End-Testing und -Monitoring im Container-Zeitalter

Tobias Schneck

© ConSol Consulting & Solutions Software GmbH

Sowohl End-2-End-Testing als auch End-2-End-Monitoring folgen dem gleichen Paradigma – sie betrachten eine Applikation aus der Sicht des End-Users. Hier darf es keine Rolle spielen, in welcher Oberflächentechnologie die Applikation geschrieben ist oder in welcher Art sie mit dem End-User in Verbindung tritt. Genau an diesem Punkt setzt das Open-Source-Tool Sakuli an.

Die Anwendungsgebiete des Open-Source-Tools reichen von Web-Clients mit oder ohne Plug-ins (wie zum Beispiel Flash) über generierte PDFs bis hin zu Rich-Clients, die automatisiert abgeprüft werden. Zudem zeigt der Artikel, wie die Container-Technologie genutzt werden kann, um vollständig reproduzierbare End-2-End-Testumgebungen aufzubauen.

Schematischer Aufbau Sakuli End-2-End-Testing und -Monitoring

Der Begriff „End-2-End“ wird oftmals in verschiedenen Kontexten verwendet. Es besteht allerdings Einigkeit darüber, dass es sich immer um die Endpunkte einer Applikation handelt, meist in Form einer Benutzeroberfläche. Diese zu testen, ist der Einsatzzweck des Open-Source-Frameworks Sakuli. Unterstützt werden alle gängigen Betriebssysteme sowie die Ausführung als Docker-Container. Die in Docker-Container verpackten Testumgebungen besitzen ebenfalls eine echte Desktop-Umgebung, was es ermöglicht, eine sogenannte „Immutable Infrastruktur“ für UIs zu schaffen. Orchestrierungslösungen wie OpenShift oder Kubernetes können darauf aufbauend wiederum eine flexible Skalierung bis in die Cloud ermöglichen. Die Frage, die sich allerdings stellt: Was haben das End-2-End-Monitoring und -Testen gemeinsam? Die Antwort ist ganz einfach, die Applikation!

Beim Testing-Use-Case wird in der Regel innerhalb der CI-Build-Pipeline das „System under Test“ (SUT) neu gebaut, die Anwendung deployed, die Tests ausgeführt und abschließend das Ergebnis an den CI-Server zurückgemeldet. Das Ziel ist es, zu überprüfen, ob das System under Test die definierten Funktionalitäten weiterhin beherrscht.

Im Gegensatz dazu steht beim End-2-End-Monitoring – auch Applikationsmonitoring genannt – das SUT bereits zur Verfügung, da es sich um das Produktivsystem handelt. Die Tests werden meist in einer getakteten Endlos-Schleife ausgeführt, zum Beispiel alle 5 Minuten, und die gesammelten Ergebnisse an ein Monitoring-System geschickt. Im Gegensatz zum klassischen Monitoring liegt der Fokus hier auf der Sicht des End-Users.

Lesen Sie auch: RESTful APIs dokumentieren

Die Kernfrage ist: Erfüllt das Produktivsystem die erwartete Funktionalität und die gewünschte Performance? Dieses „funktionale“ Monitoring ermöglicht es, die Key-Features einer Applikation zu überwachen, ohne dafür eine explizite technische Kennzahl im Monitoring-System definiert zu haben. Wird zum Beispiel der User-Login dadurch verhindert, dass versehentlich alle Accounts abgelaufen sind, wird dies erkannt, obwohl dafür kein expliziter Datenbank-Check aufgesetzt wurde. Durch das kontinuierliche Tracken der Login-Laufzeiten wird zudem erkannt, wann Laufzeitspitzen zu verzeichnen sind oder ein Alarming durchzuführen ist.

Der große Vorteil ist, dass dort keine technische Laufzeit gemessen wird, sondern die Laufzeit aus End-User-Sicht, die das Zusammenspiel aller Komponenten beinhaltet – von der Eingabe bis zum Laden der ersten Seite nach dem Login. Ein weiterer Anwendungsfall wäre, durch Graphen die Login-Zeiten von verschiedenen WAN-Standorten zu vergleichen und Bottlenecks in der WAN-Anbindung zu identifizieren.

Sakuli Komponenten

Die Architektur des Open-Source-Frameworks, besteht im Wesentlichen aus drei Hauptkomponenten: dem Starter, der Testdefinition und der Ergebnisauswertung.

Komponenten des Sakuli-Frameworks

Starter

Der Starter hat die Aufgabe, die Testausführung zu initialisieren, die Testsuite zu laden und die Testumgebung zu konfigurieren. Nach der erfolgreichen Sakuli – Installation kann die Testausführung per Commandline wie folgt gestartet werden:

sakuli run [OPTIONS]

Nachdem die Testsuite erfolgreich lokalisiert wurde, beginnt die Testausführung mit den in der <sakuli-suite-path>/testsuite.properties Datei hinterlegten Parametern. Dort wird unter anderem festgelegt, welcher Browser zur Testausführung genutzt wird oder welche Threshold-Zeiten gesetzt sind:

#######################################################################################
# TEST-SUITE-META-PROPERTIES
#######################################################################################

# The test suite ID is a unique ID, which identifies the same test suite
# over all executions and configuration changes.
testsuite.id=example_xfce

#######################################################################################
# OPTIONAL-PROPERTIES for the test suite
#######################################################################################

# The warning runtime threshold (seconds) estimates the execution time of the complete
# test suite. If the warning time is exceeded, the test suite will get the state
# 'WARNING'.
testsuite.warningTime=30

# The critical runtime threshold (seconds) estimates the execution time of the complete
# test suite. If the cirtical time is exceeded, the test suite will get the state
# 'CRITICAL'.
testsuite.criticalTime=60

#######################################################################################
# OVERWRITE-PROPERTIES
#######################################################################################
#
### FOR EXAMPLE overwrite the default browser ###
#
# DEFAULT: firefox
testsuite.browser=chrome
....

Listing 1: Beispiel testsuite.properties

Das vollständige Referenz-File findet sich unter Sakuli – Default Properties. Zusätzlich können diese Properties zur Laufzeit mit der Kommandozeile überschrieben werden, wie in diesem Beispiel der Warning-Threshold:

sakuli run <sakuli-suite-path> -D testsuite.warningTime=50

Testdefinition

Um es zu ermöglichen, innerhalb eines geschlossenen Ausführungskontextes sowohl Web-Content als auch nativen UI-Content zu testen, greift Sakuli intern auf die Funktionen der beiden Open-Source-Tools Sahi OS und Sikuli zurück. Die Sahi-Komponente kümmert sich um das Web-Testing, Sikuli um den nativen Content. Der Best-of-Breed-Ansatz ermöglicht es, für jeden Content-Type das richtige Werkzeug zu benutzen, ohne einen Kontext-Sprung zu haben.

Web-Testing-Frameworks wie Sahi können anhand des von einer HTML-Seite abgeleiteten Document-Object-Models (DOM) alle enthaltenen Elemente auf Basis von Namen, IDs oder CSS-Klassen identifizieren. Über diese so genannten Identifier wird die Seite innerhalb des Browsers ferngesteuert oder mit Werten befüllt. Der neue, veränderte Zustand wird darauffolgend mit Asserts validiert. Zum Beispiel wird geprüft, ob im Textfeld der Produkttext des vorher ausgewählten Produkts angezeigt wird.

Angular - Eine Einführung

Angular – eine Einführung

Manfred Steyer

In diesem Videotutorial erklärt Manfred Steyer alles, was man für einen professionellen Umgang mit Angular benötigt und zeigt anhand eines praxisnahen Beispiels, wie man Services und Dependency Injection integriert, Pipes zur Formatierung von Ausgaben nutzt, Komponenten mit Bindings verwendet, Angular-Anwendungen mit Modulen strukturiert und Routing gebraucht.

Besteht allerdings die Anforderung, Rich-Clients oder ein generiertes PDF zu validieren, stoßen reine Web-Testing-Tools an ihre Grenzen. Hier bietet Sakuli einen Ausweg, da zusätzlich zu den DOM-basierten Elementen auch Inhalte außerhalb des Browser-DOMs durch die Nutzung der Sikuli-Funktionen getestet werden können. Konkret werden bei diesem Best-of-Breed-Ansatz zusätzlich zur Webseiten-Manipulation User-Aktionen per Maus und Tastatur auf dem nativen UI des Betriebssystems ausgeführt. Außerdem ist es möglich, Bildschirminhalte per Bildmusterabgleich zu kontrollieren und zu validieren.

Ist es zum Beispiel aufgrund eines kryptischen DOM-Selektors nicht möglich, einen HTML-Button zu erreichen, kann dies mithilfe nativer Bilderkennung über das Aussehen des Buttons durchgeführt werden. Die Identifizierung des Buttons erfolgt mittels Bildmuster, die im Testfall durch kleine Screenshot-Snippets definiert und während der Testausführung mit der aktuellen Anzeige verglichen werden. So kann auch innerhalb eines Browser-Tests ein natives PDF im Test geöffnet, ferngesteuert und validiert werden. Das folgende Code-Beispiel zeigt einen Testcase, der im Chrome-Browser über die „PDF speichern“-Funktion ein PDF erstellt, es in einem neuen Browser-Tab öffnet und abschließend validiert, ob das PDF die erwarteten Elemente enthält. Dieser Test gewährleistet, dass im PDF alle gewünschten Report-Elemente enthalten sind und nicht aufgrund eines Fehlers im CSS des Drucklayouts Elemente fehlen.

//sakuli-test-suite/testcase_1/tc.js

//open bakery application
_navigateTo("http://bakery-web-server:8080/bakery/");
_isVisible(_heading1("Cookie Bakery Application"));
_highlight(_heading1("Cookie Bakery Application"));

//open print preview and save PDF
env.type("p", Key.CTRL);
screen.find("save_button").highlight().click().type(Key.ENTER);

//open pdf in new tab and validate
env.type("tl", Key.CTRL).paste(getPDFpath()).type(Key.ENTER);
screen.waitForImage("pdf_place_order.png", 5).highlight();
[
    "pdf_blueberry.png",
    "pdf_caramel.png",
    "pdf_chocolate.png"
].forEach(function (imgPattern) {
    screen.find(imgPattern).highlight();
});

pdf_place_order.png:
 
pdf_blueberry.png:
 
pdf_caramel.png:
 
pdf_chocolate.png:
 

Listing 2: Beispiel PDF-Validierung im Browser

Beispiel PDF-Validierung im Browser, Sakuli – Bakery Example

Wird auf die Web-Komponente von Sakuli gänzlich verzichtet, können selbst native Rich-Clients wie eine Swing-Anwendung oder ein SAP-Rich-Client problemlos getestet werden. Ein weiteres Testszenario wäre, das Zusammenspiel zweier Anwendungen wie die Web-Eingabe eines Anfrageformulars mit Übermittlung an das Backend eines CRM-Systems mit Rich-Client zu testen. Den Einsatzmöglichkeiten sind hier nahezu keine Grenzen gesteckt, einen Überblick bietet das Projekt Sakuli – Examples.

Sakuli-Tests lassen sich auf zwei Arten erstellen. Zum einen über die Java DSL und zum anderen über eine JavaScript-Definition. Welche Sprache für das eigene Projekt geeignet ist, entscheidet sich meist an der bestehenden Infrastruktur und dem Wissensstand in der jeweiligen Programmiersprache.

Testdefinition JavaScript

Die Testdefinition auf JavaScript-Basis bietet gerade für Programmieranfänger einen einfachen Weg, in das Thema automatisiertes UI-Testen einzusteigen, da weder Compiler noch tieferes Wissen über das JavaScript-Ökosystem notwendig sind. Das Tutorial Sakuli – First Steps bietet hierfür einen idealen Einstiegspunkt.

Aufbau Sakuli Testsuite (JavaScript)

Der Aufbau einer Sakuli-Testsuite gestaltet sich, wie oben dargestellt, sehr einfach. Unter dem Testsuite-Ordner, in diesem Fall example, wird folgendes definiert:

  • Datei testsuite.suite: Legt fest, welche unterliegenden Testcases – hier der Testcase demo – mit jeweiliger Start-URL ausgeführt werden soll:
// ... define your tescases like:
// folder-of-testcase http://www.startURL.de
//
demo/sakuli_demo.js http://sahi.example.com/_s_/dyn/Driver_initialized
  • Datei: testsuite.properties: Legt die Parameter fest, mit denen die Testsuite ausgeführt werden soll, also Browser, Thresholds, Forwarder-Module usw. (siehe die Punkte „Starter“ und „Ergebnisauswertung“).
  • Testcase demo: Beinhaltet sowohl die eigentliche Testdefinition sakuli_demo.js als auch die zugehörigen Screenshot-Snippets *.png für die native Bilderkennung.

    Der nachfolgende Beispiel-Testcase example_xfce testet unter der Linux-Oberfläche „Xfce“ zuerst einfachen HTML-Content, öffnet anschließend den nativen Gnome Calculator, um die Berechnung 525+100 durchzuführen, und letztendlich das Ergebnis 625 zu validieren. Je nach Basis-Betriebssystem Ubuntu oder CentOS werden unterschiedliche Screenshot-Snippets mithilfe der Methode checkCentOS() geladen, was eine flexible Testdefinition für unterschiedliche UI-Umgebungen abbildet.

    Dieser recht einfache Use-Case zeigt dennoch, wie nahtlos ohne Kontextwechsel sowohl HTML als auch native Applikationen in verschiedenen Umgebungen getestet werden können. Angemerkt sei an dieser Stelle, dass der gleiche Testcase sich unter Windows/MacOS nur durch die Applikationspfade und Screenshot-Snippets unterscheidet, siehe Sakuli – Example Testsuites.

    //case1/sakuli_demo.js
    _dynamicInclude($includeFolder);
    var testCase = new TestCase(20, 30);
    var env = new Environment();
    var screen = new Region();
    var appCalc = new Application("gnome-calculator");
    
    function checkCentOS() {
        var dist = env.runCommand('cat /etc/os-release').getOutput();
        if (dist.match(/NAME=.*CentOS.*/)) {
            Logger.logInfo('Detected distribution: CentOS  >> overwrite some image patterns');
            testCase.addImagePaths("centos");
        }
    }
    
    try {
        checkCentOS();
        _highlight(_link("SSL Manager"));
        _highlight(_link("Logs"));
        _highlight(_link("Online Documentation"));
        _highlight(_link("Test Pages"));
        _highlight(_link("Sample Application"));
    
        testCase.endOfStep("Test Sahi landing page", 5);
        appCalc.open();
        screen.waitForImage("calculator.png", 5).mouseMove();
    
        env.type("525");
        var calcRegion = appCalc.getRegion();
        calcRegion.find("plus.png").click().type("100");
        calcRegion.find("result.png").click();
        screen.waitForImage("625.png", 5);
        testCase.endOfStep("Calculation", 10);
    
    } catch (e) {
        testCase.handleException(e);
    } finally {
        appCalc.close(true); //silent
        testCase.saveResult();
    }
    

    calculator.png (Ubuntu):
     
    calculator.png (CentOS):
     
    plus.png:
     
    result.png:
     
    625.png:
     
    Listing 3: Beispiel Java-Script Testdefinition: Gnome Calculator

    Sakuli Testausführung Gnome Calculator

    Testdefinition durch die Java DSL

    Die Java DSL wird klassisch mithilfe von Maven direkt in den Build-Lifecycle eingehängt und wie im unteren Beispiel per TestNG zur Ausführung gebracht:

    public class FirstExampleTest extends AbstractSakuliTest {
    
         private static final String CITRUS_URL = "http://www.citrusframework.org/";
    
         @Override
         protected TestCaseInitParameter getTestCaseInitParameter() throws Exception {
             return new TestCaseInitParameter("test_citrus")
                     .withWarningTime(30)
                     .withCriticalTime(50);
         }
    
         @Test
         public void testCitrusHtmlContent() throws Exception {
             browser.navigateTo(CITRUS_URL);
             ElementStub heading1 = browser.paragraph("Citrus Integration Testing");
             heading1.highlight();
             assertTrue(heading1.isVisible());
    
             ElementStub download = browser.link("/Download v.*/");
             download.highlight();
             assertTrue(download.isVisible());
             download.click();
    
             ElementStub downloadLink = browser.cell("2.6.1");
             downloadLink.highlight();
             assertTrue(downloadLink.isVisible());
         }
    
         @Test
         public void testCitrusPictures() throws Exception {
             browser.navigateTo(CITRUS_URL);
             Region screen = new Region();
             screen.find("citrus_logo.png").highlight();
             screen.type(Key.END);
             screen.find("consol_logo.png").highlight();
         }
     }
    

    citrus_logo.png:
     
    consol_logo.png:
     
    Listing 4: Beispiel Java DSL Test

    Java-Entwickler können ihre gewohnte Maven-Build-Umgebung weiterhin nutzen, um die Tests zur Ausführung zu bringen. Voraussetzung ist lediglich, dass ein reales Display zur Laufzeit zur Verfügung steht. Um Tests „headless“ auszuführen, bieten sich die Sakuli-Java-Docker-Images an, siehe Punkt „Containerized Sakuli“.

    Ergebnisauswertung

    Unabhängig von der gewählten Testdefinitionssprache bietet Sakuli mehrere Forwarder-Module an, die die Ergebnisse der Testausführung auswerten und an das jeweilige Zielsystem weiterleiten. Entsteht während der Testausführung ein Fehler, wird automatisch zum Fehlerzeitpunkt ein Screenshot erstellt und an die entsprechenden Forwarder-Systeme zusammen mit der Testzusammenfassung weitergeleitet. Die nachfolgende Tabelle bietet einen Überblick, welche Forwarder in der Version 1.1.0 zur Verfügung stehen:

    Standard-Forwarder Technologie Anwendungsgebiete
    Standard-Forwarder
    • Log-Files und Screenshots
    • Kommandozeilenausgabe
    • Continuous-Integration-Server
    • Lokale Testläufe
    Datenbank-Forwarder
    • JDBC-SQL
    • Anbindung an Nagios durch check_mysql_health
    • Persistente Speicherung und Auswertung der Ergebnisse
    • Schnittstelle zu Drittsystemen
    Gearman-Forwarder
    • Gearman Result Queuing
    • Anbindung an Nagios durch passiven Check
    • Vorkonfigurierte Graph- und Screenshot-Templates für OMD
    Icinga2-Forwarder
    • REST API
    • JSON Data
    • Anbindung an Icinga2 durch passiven Check
    • Vorkonfigurierte Graph-Templates für OMD
    CheckMK-Forwarder
    • Agent Spool File
    • Anbindung an CheckMK durch anpassbares Spool-File
    • Vorkonfigurierte Service-Templates

    Tabelle 1: Überblick Ergebnis-Forwarder-Module

    Der Standard-Forwarder wird meist innerhalb eines CI-Builds oder zur Ausführung auf der Commandline genutzt. Läuft die Testsuite wie erwartet durch, wird der Prozess mit Exit-Code 0 beendet, was zum Beispiel von einem Jenkins-CI-Server innerhalb eines Jobs ausgewertet wird. Entsteht eine Laufzeitüberschreitung in Form von einer Warning oder ein Fehler wird ein entsprechender Exit-Code zwischen 1 und 6 zurückgegeben. Um nachzuvollziehen, was den Fehler oder die Warning verursacht hat, werden die notwendigen Informationen wie folgt bereitgestellt:

    • Commandline-Ausgabe
    • Log-File unter <testsuite-folder>/_logs/_sakuli.log
    • Screenshots unter <testsuite-folder>/_logs/_screenshots

    In einem späteren Release wird es auch die Möglichkeit geben, einen ansprechenden HTML-Report zu generieren.

    Die verschiedenen Monitoring-Forwarder können die Ergebnisse der Testausführung sehr einfach an unterschiedliche Monitoring-Systeme weiterleiten. Sind die Ergebnisse zum Beispiel per Gearman-Protokoll (leichtgewichtiges Framework für Verteilung und Auswertung von Jobs) an ein OMD-System (Open-Monitoring-Distribution) mit Nagios-Core zu schicken, wird der Forwarder in den testsuite.properties wie folgt aktiviert:

    # <sakuli-suite-path>/testsuite.properties
    #
    sakuli.forwarder.gearman.enabled=true
    sakuli.forwarder.gearman.server.host=omd-nagios
    sakuli.forwarder.gearman.server.port=4730
    sakuli.forwarder.gearman.nagios.hostname=sakuli_client
    
    # (optional) encryption
    #
    sakuli.forwarder.gearman.encryption=true
    sakuli.forwarder.gearman.secret.key=pass4encrypt
    

    Listing 5: Aktivierter Gearman-Forwarder in testsuite.properties

    Innerhalb des Monitoring-Cores (Nagios) wird der Monitoring-Check wie folgt konfiguriert:

    # <monitoring-site>/etc/nagios/conf.d/sakuli_objects.cfg
    # requires a running gearman server on the monitoring host
    define service {
      service_description            example_xfce
      host_name                      sakuli_client
      use                            tpl_s_sakuli_gearman
    }
    
    define host {
      host_name                      sakuli_client
      alias                          Sakuli docker containers
      address                        127.0.0.1
      use                            generic-host
    }
    

    Listing 6: Service-Check sakuli_objects.cfg

    Damit steht der neue passive Service-Check zur Verfügung und nimmt Ergebnisse von einem oder mehreren Sakuli-Clients entgegen. Es können sowohl Lauf- und Schwellwertzeiten in Graphen als auch die mitgeschickten Fehler-Screenshots betrachtet werden.

    Sakuli-Service-Check mit Fehler-Screenshot in OMD

    Containerized Sakuli

    Bereits vorgefertigte Docker-Images, die das Aufsetzen einer End-2-End-Testing oder -Monitoring Umgebung stark vereinfachen, gibt es zum einen für die OMD Monitoring-Komponente und zum anderen für den Sakuli-Test-Client. Für das Aufsetzen eines CI-Servers ist kein besonderes Image notwendig, da diese beispielsweise von Jenkins selbst bereitgestellt werden. Das zusätzlich zu den nativen Installern (Windows, Linux, Mac) in Docker-Image ausgelieferte Sakuli enthält bereits eine vollständige Testumgebung mit nativer UI und vorinstallierten Browsern (Chrome und Firefox). Für die Testerstellung wird generell sowohl Java als auch JavaScript unterstützt. Derzeit werden die folgenden unterschiedlichen Umgebungen als Docker-Images angeboten:

    Docker-Image Betriebssystem UI Testausführung
    consol/sakuli-centos-xfce CentOS 7 Xfce4 Tests in JavaScript (Rhino Engine)
    consol/sakuli-centos-xfce-java CentOS 7 Xfce4 Java 8, Maven, TestNG-Test
    consol/sakuli-ubuntu-xfce Ubuntu 16.04 Xfce4 Tests in JavaScript (Rhino Engine)
    consol/sakuli-ubuntu-xfce-java Ubuntu 16.04 Xfce4 Java 8, Maven, TestNG-Test
    consol/sakuli-centos-icewm CentOS 7 IceWM Tests in JavaScript (Rhino Engine)
    consol/sakuli-centos-icewm-java CentOS 7 IceWM Java 8, Maven, TestNG-Test
    consol/sakuli-ubuntu-icewm Ubuntu 16.04 IceWM Tests in JavaScript (Rhino Engine)
    consol/sakuli-ubuntu-icewm-java Ubuntu 16.04 IceWm Java 8, Maven, TestNG-Test

    Tabelle 2: Docker-Images Sakuli-Client

    Als Einstiegspunkt für die Erstellung von eigenen Test-Umgebungen bietet es sich an, eines der Beispiel-Projekte von GitHub zu kopieren und dieses auf die eigenen Bedürfnisse anzupassen. Nachdem beispielsweise die JavaScript-basierten Tests erstellt sind, kann die Testdefinition sehr einfach vom lokalen Dateisystem in den Sakuli-Container gemountet werden. Mithilfe von Docker Compose werden die Mount-Punkte festgelegt und mit dem Befehl docker-compose up zur Ausführung gebracht. Auch parallele Testausführungen sind damit einfach aufzusetzen, wie das docker-compose.yml zeigt:

    # Run test in two separated environments: Ubuntu/Firefox and CentOS/Chrome
    
    sakuli_test_ubuntu_firefox:
      image: consol/sakuli-ubuntu-xfce
      volumes:
      - ./example_xfce:/headless/sakuli/test                # mount sakuli testsuite
      ports:
      - 5911:5901
      - 6911:6901
      command: run /headless/sakuli/test                    # start mount testsuite in firefox
    
    sakuli_test_centos_chrome:
      image: consol/sakuli-centos-xfce
      volumes:
      - ./example_xfce:/headless/sakuli/test                # mount sakuli testsuite
      ports:
      - 5912:5901
      - 6912:6901
      command: run /headless/sakuli/test -browser chrome    # start mount testsuite in chrome
    

    Listing 7: Parallele Sakuli-Container (Ubuntu/Firefox, CentOS/Chrome) docker-compose.yml

    Parallele Sakuli-Container (Ubuntu/Firefox, CentOS/Chrome)

    Um die erstellten Tests nun kontinuierlich zur Ausführung zu bringen, reicht der reine Aufruf von docker-compose up nicht aus. Wird eine Umgebung mehrfach nacheinander mit docker-compose up gestartet, werden entgegen des vermuteten Verhaltens die Container nicht frisch gestartet, sondern nur „wiederbelebt“. Eine absolute Nachvollziehbarkeit und Reproduzierbarkeit kann nur erreicht werden, wenn die Container bei jeder Ausführung von Scratch starten. Das heißt, es ist (derzeit) notwendig, Docker-Compose in entsprechende Helfer-Skripte zu wrappen, die dieses Verhalten sicherstellen. Die Skripte können dann ebenfalls dazu genutzt werden, die Tests aus einem CI-System zu starten oder eben als kontinuierliche Schleife für Monitoring-Checks.

    Ein komplettes Beispiel ist auf github.com/toschneck/sakuli-example-bakery-testing zu finden. Dort enthalten ist ebenfalls Beispielcode, wie eine für Sakuli vorkonfigurierte OMD-Monitoring-Instanz per Docker Compose aufgesetzt werden kann. Hierfür stehen die folgenden Images zur Verfügung:

    Docker-Image Betriebssystem Umgebung
    consol/omd-labs-centos-sakuli CentOS 7 OMD Labs + Sakuli Add-On
    consol/omd-labs-debian-sakuli Debian 8 OMD Labs + Sakuli Add-On
    consol/omd-labs-ubuntu-sakuli Ubuntu 16.04 OMD Labs + Sakuli Add-On

    Tabelle 3: Docker-Images OMD mit Sakuli Add-On

    ### Run OMD with Sakuli Add-On an mounted data storage
    
    omd:
      image: consol/omd-labs-centos-sakuli
      volumes:
      -./site/local:/omd/sites/demo/local
      -./site/etc:/omd/sites/demo/etc
      -./site/var:/omd/sites/demo/var
      ports:
      - 8443:443                   # HTTPS port
      - 4730:4730                  # gearmand port
    

    Listing 8: Startup OMD mit Sakuli Add-On docker-compose.yml

    OpenShift / Kubernetes

    Aufbauend auf den beschriebenen Docker-Images ist es möglich, die Testausführung mit Hilfe von Kubernetes oder OpenShift in die Private oder Public Cloud zu verlagern. Dies bringt Vorteile, wenn die Testausführungen sehr flexibel gestaltet werden müssen und die Ressourcenverteilung automatisiert zu erfolgen hat. CI- und Monitoring-Systeme können flexibel die Testausführung triggern und die Ergebnisse auswerten, ohne sich um die Ressourcenbereitstellung zu kümmern. Ab Version 1.1.0 werden sowohl Kubernetes als auch OpenShift-Deployments von Sakuli unterstützt. Das nachfolgende Beispiel aus dem Repository github.com/ConSol/sakuli zeigt, wie ein Pod in einem OpenShift-Cluster gestartet werden kann:

    ### git repo: https://github.com/ConSol/sakuli
    ###
    oc process -f docker/openshift/openshift.sakuli.example.pod.run.yaml -v E2E_TEST_NAME=my-example | oc create -f -
    # ....
    objects:
    ### POD config (run one time)
    - apiVersion: v1
      kind: Pod
      metadata:
        labels:
          application: ${E2E_TEST_NAME}
        name: ${E2E_TEST_NAME}-pod
      spec:
        ### ensure that the pod won't start again
        restartPolicy: Never
        dnsPolicy: ClusterFirst
        terminationGracePeriodSeconds: 5
        containers:
        - name: ${E2E_TEST_NAME}-pod-c1
          image: ${IMAGE}
          imagePullPolicy: Always
          ### checks that vnc server is up and running
          livenessProbe:
            tcpSocket:
              port: 5901
            initialDelaySeconds: 1
            timeoutSeconds: 1
          ### checks if http-vnc connection is working
          readinessProbe:
            httpGet:
              path: /
              port: 6901
              scheme: HTTP
            initialDelaySeconds: 1
            timeoutSeconds: 1
    # ....
    

    Listing 9: Ausschnitt OpenShift-Template docker/openshift/openshift.sakuli.example.pod.run.yaml

    Fazit

    Traditionelle End-2-End-Testing und -Monitoring-Ansätze haben im Hinblick auf die wachsende Applikationsvielfalt, die Komplexität der Web-Frameworks und die Unterschiedlichkeit der Clients immer größere Schwierigkeiten, die Qualitätsansprüche zu erfüllen. Gerade die Flexibilität der Container-Technologie sowie deren Skalierbarkeit, die nur durch Hardware-Ressourcen beschränkt ist, eröffnet ganz neue Möglichkeiten, um eine Vielzahl von Testsystemen zu betreiben und genügend parallele Test-Clients zur Verfügung zu stellen.

    Der aufgezeigte Ansatz bietet hier einen Ausweg, da selbst UI-Tests in echten Desktop-Umgebungen durch die Container-Technologie effektiv automatisierbar werden. Die Nutzung der Docker-Images als fixe Basis für den Aufbau einer Testumgebung bietet den Vorteil, dass die gewünschte Immutable Infrastruktur auch für UI-Tests zur Realität wird. Die gewonnene Verlässlichkeit, dass ein Testsystem beziehungsweise Test-Client unabhängig von Ort und Zeit der Ausführung fortwährend den gleichen Startzustand besitzt, verbessert nicht nur die Stabilität der Tests, sondern vereinfacht auch die Fehlersuche, da jede Umgebung eins zu eins auf dem Entwickler-Laptop lokal nachgestellt werden kann.

    Lesen Sie auch: DevOps gilt auch für Tester

    Sakuli hat das Ziel, die verwendete Testumgebung möglichst nah an die Umgebung des End-Users zu bringen, da es wichtig ist, echte Browser in echten Desktop-Umgebungen zu nutzen. Selbst der Rich-Client oder das zu öffnende PDF der Bestellbestätigung darf kein No-Go sein. Sakuli bietet dies als Open-Source-Lösung sowohl für UI-Tests innerhalb von CI-Systemen, als auch für kontinuierliches, funktionales End-2-End-Monitoring an.

    Die nächsten Ziele der Entwickler sind zum einen, die Verwaltung und Auswertung der Testsuites durch eine UI zu vereinfachen und zum anderen, Selenium als alternative Web-Testing-Engine anzubieten. Selenium ergänzt den bestehenden Best-of-Breed-Ansatz, da bereits vorhandene Tests sehr einfach erweitert werden können. Weiter wird es angestrebt, durch eine vergleichbare Windows-Container-Implementierung auch die Ausführung unter Windows skalierbar bis in die Cloud zu gestalten. Weiterführende Informationen sind unter github.com/ConSol/sakuli zu finden oder per Twitter @sakuli_e2e zu erfahren.

Geschrieben von
Tobias Schneck
Tobias Schneck
Tobias Schneck ist Mitbegründer des Open Source-Test-Frameworks Sakuli und ist als Java-Entwickler mit Schwerpunkt Testautomatisierung bei der ConSol Software GmbH in München tätig. Als Konferenz-Speaker und Organisator des Agile Testing @Munich Meetups interessiert er sich stets für innovative Technologien.
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.