zurück zum Artikel

recheck-web – ein etwas anderer Ansatz zur Testautomatisierung

Jeremias Rößler
recheck-web – ein etwas anderer Ansatz zur Testautomatisierung

Das Testwerkzeug recheck-web setzt auf einen Golden-Master-basierten Ansatz. Dadurch können Entwickler es in diversen Testszenarien einsetzen.

recheck-web ist ein Golden-Master-basiertes Testwerkzeug. Da es im Prinzip gerenderte Webseiten miteinander vergleicht, lassen sich damit auch Cross-Browser-Testing, Cross-Platform-Testing und andere Testszenarien umsetzen.

Um eine Anmeldung einer Webanwendung zu testen, könnte ein typischer Selenium-Test etwa so aussehen:

public class MySeleniumTe st {

RemoteWebDriver driver;

@Before
public void setup() {
driver = new ChromeDriver();
}

@Test
public void login() throws Exception {
driver.get("https://assets.retest.org/demos/app/demo-app.html");

driver.findElement(By.id("username")).sendKeys("Simon");
driver.findElement(By.id("password")).sendKeys("secret");
driver.findElement(By.id("sign-in")).click();

assertEquals(driver.findElement(By.tagName("h4")).getText(), "Success!");
}

@After
public void tearDown() throws InterruptedException {
driver.quit();
}
}

Das ist ein einfacher Test, der eine bestimmte URL öffnet, dann Eingabefelder anhand ihrer unsichtbaren Element-IDs findet, um Benutzernamen und Passwort einzugeben, und schließlich auf Login klickt. Wie derzeit üblich, verwendet der Test am Ende eine Unit-Test-Bibliothek, um das korrekte Ergebnis der Testausführung mit einer "assert"-Anweisung zu überprüfen. Konkret wird geprüft, ob der Text "Success!" angezeigt wird.

Mehr Infos

Die im Artikel verwendeten Beispiele finden sich auf GitHub [1]. Zur Verwendung und Installation der gezeigten Werkzeuge gibt es ein ausführliches Tutorial auf heise Developer [2].

Jetzt können Entwickler das HTML der zu testenden Website ändern. Sie könnten zum Beispiel die
CSS-Deklaration <link href="./files/main.css" rel="stylesheet"> bearbeiten. Das Ändern eines einzelnen Zeichens der URL führt dazu, dass die Website ohne Formatierung angezeigt wird.

Formatierte und unformatierte Website, Unterschiede in Zeichen (Abb. 1)

Formatierte und unformatierte Website, Unterschiede in Zeichen (Abb. 1)

Diese Änderung entspricht jedoch einem Fehler. Wenn man den Test ausführt, zeigt er allerdings kein Problem und läuft immer noch fehlerfrei durch. Das ist eindeutig nicht das, was man von dem Test erwartet. Probiert sei nun stattdessen, die für den Benutzer unsichtbaren Element-IDs zu ändern oder zu entfernen. Da diese IDs nicht zu erkennen sind, hat die Änderung aus Benutzersicht keinen Einfluss auf die eigentliche Website. Aber wenn man den Test jetzt ausführt, ist zu sehen, dass er mit einer NoSuchElementException abbricht. Die für den Nutzer irrelevante Änderung hat den Test nicht nur fehlschlagen lassen, sondern auch seine Ausführung verhindert – ihn also "gebrochen". Tests, die größere Änderungen ignorieren, aber bei unsichtbaren brechen, sind der aktuelle Standard in der Testautomatisierung. Das ist im Grunde genommen das Gegenteil dessen, was man sich von den Tests wünscht.

Nun ist es an der Zeit, den Originaltest zu nehmen und den Selenium-Treiber in einen RecheckDriver zu stecken:

driver = new RecheckDriver(new ChromeDriver()); 

Bei entsprechender Projektkonfiguration ist sonst nichts weiter nötig. Die Prüfung mittels assert kann man nun löschen. Entfernt man das CSS von der Website, schlägt der Test plötzlich mit vielen Unterschieden fehl.

Anzeige des fehlschlagenden Tests in Eclipse (Abb. 2)

Anzeige des fehlschlagenden Tests in Eclipse (Abb. 2)

Ändern oder entfernen Entwickler stattdessen die Element-IDs, wird der Test trotzdem erfolgreich ausgeführt (funktioniert entsprechend auch mit Name, CSS-Klasse, XPath etc.). Diese Fähigkeit wird als "Unzerbrechlichkeits"-Feature von recheck-web bezeichnet. So sollten sich Tests verhalten: Änderungen, die für den Benutzer wichtig sind, erkennen und nicht an Änderungen brechen, die für den Benutzer irrelevant sind.

recheck-web [3] ist ein kostenloses Open-Source-Tool, das auf Selenium basiert. Es funktioniert nach dem
Golden-Master-Prinzip, was im Wesentlichen bedeutet, dass es beim ersten Durchführen des Tests eine Kopie der gerenderten Website erstellt, und nachfolgende Durchläufe des Tests vergleichen den aktuellen Zustand mit dieser Kopie (dem Golden Master). So kann der Test erkennen, ob sich die Website auf unerwünschte Weise verändert hat. So kann recheck-web nach der Änderung einer ID das entsprechende Element noch identifizieren, indem es einfach in den Golden Master (wo die ID noch vorhanden ist) schaut und das Element dort findet. Mit zusätzlichen Eigenschaften wie XPath, HTML-Name und CSS-Klassen identifiziert recheck-web das Element auf der veränderten Website und gibt es an Selenium zurück. Der Test kann dann wie bisher mit dem Element interagieren, und die Änderung werden einfach als solche gemeldet.

&quot;Unzerbrechlichkeit&quot; veranschaulicht (Abb. 3)

"Unzerbrechlichkeit" veranschaulicht (Abb. 3)

Golden-Master-basierte Tests haben im Allgemeinen zwei wesentliche Nachteile:

  1. Es ist oft schwierig, irrelevante Änderungen zu ignorieren. Viele Änderungen sind uninteressant und problemlos (z.B. Zeit- und Datumsänderungen sowie Zufalls-IDs). Aus dem gleichen Grund, aus dem Git die .gitignore-Datei verwendet, um Log-Dateien und andere temporäre und uninteressante Dateien und Artefakte zu ignorieren, nutzt recheck-web die recheck.ignore-Datei. Und mit einer Git-ähnlichen Syntax ist es einfach festzulegen, welche Unterschiede ignoriert werden sollen.
  2. Es ist oft umständlich, Redundanzen zu pflegen. Mehrere Golden Master haben oft eine gewisse, teilweise sogar eine hohe Überschneidung. Dann ist die gleiche Änderung mehrfach zu prüfen und zu bestätigen, was die bei der einfacheren Testerstellung erzielte Effizienz schnell zunichte macht. recheck-web kommt mit einer eigenen CLI, die sich um diese lästige Aufgabe kümmert. Mit ihr (oder der kommerziellen GUI) können Nutzer dieselbe Änderung für dasselbe Element auf alle Golden Master oder einfach global alle Änderungen anwenden oder ignorieren.

Das Beispiel zeigt beide Nachteile: Die geänderte ID wurde nicht angezeigt, da in der recheck.ignore-Datei das ID-Attribut über attribute=id als ignoriert angegeben wurde. Das Entfernen dieser Regel führt dazu, dass der Test fehlschlägt – obwohl er nicht bricht. Das heißt, der Test wird weiterhin ausgeführt und die geänderte ID als solche angezeigt. Der obige Test verwendet den impliziten Prüfmechanismus, der nach jeder Aktion automatisch das Ergebnis überprüft. Das Öffnen der URL, die Eingabe des Benutzernamens und die Eingabe des Passworts sind drei Aktionen, die auf derselben Seite durchgeführt werden. Somit wird die geänderte ID dreimal angezeigt. Alle drei Instanzen lassen sich mit einem einzigen Aufruf von recheck commit --all tests.report auf der Kommandozeile behandeln. Die Änderung führt dazu, dass nun auch der recheck-web-Test fehlschlägt, da die ID aus dem Golden Master entfernt wurde.

Das verlangt nach einem weiteren Feature von recheck-web – der retestId. Die Grundidee ist es, ein zusätzliches Attribut in die Kopie der Website einzufügen. Da es nur in der Kopie und nicht auf der eigentlichen Website vorhanden ist, kann es von Änderungen nie betroffen sein (es sei denn, das Element wird vollständig entfernt). Man nennt das eine virtuelle konstante ID. Auf diese retestId lässt sich nun im Test Bezug nehmen. Entwickler müssen einfach den Aufruf von zum Beispiel By.id("username") durch By.retestId("username") ersetzen, und das Problem ist gelöst. Der Kniff adressiert auch Fälle, in denen Elemente schwer zu referenzieren sind, da sie gar keine HTML-ID haben.

Regressionstests finden keine Fehler in einem System. Damit sind sie keine Tests im eigentlichen Sinne. Sie schützen existierende Funktionen vor unerwünschten Seiteneffekten durch Änderungen. Damit sind Regressionstests ein Werkzeug zur Kontrolle von Änderungen. Es gibt bereits ein System, das diesen Zweck erfüllt: das Versionskontrollsystem. Allerdings verwaltet es nur statische Artefakte wie Code und Konfigurationsdateien. Das Verhalten der Software entsteht aber zur Laufzeit.

Diese Lücke schließt man mit automatischen Tests, die das Laufzeitverhalten der Software prüfen. Wie die Testpyramide (Mike Cohn, Succeeding with Agile, 2009) rät, sollten aber für User Interfaces so wenige Tests wie möglich automatisiert werden, da diese viel Aufwand bedeuten, langsam und brüchig sind. Zumindest zwei der drei Annahmen lassen sich mit dem Prinzip der Golden-Master-basierten Tests abschwächen: Sie sind einfacher zu erstellen und deutlich robuster.

Was wäre Git ohne die .gitignore-Datei? Das Ausfiltern irrelevanter Änderungen ist eine der wichtigsten Fähigkeiten eines Versionsverwaltungssystems. Wenn man nun Golden-Master-Testing als entsprechende Erweiterung versteht, ist das Ausfiltern dieser Änderungen auch hier von enormer Bedeutung. Traditionelle Assertion-basierte Tests ignorieren mehr als 99 Prozent der Änderungen. Stattdessen, ähnlich wie bei Git ohne .gitignore-Datei, wird recheck-web jede Änderung melden. Es liegt also am Nutzer, Änderungen zu ignorieren, die für ihn nicht von Interesse sind.

recheck-web kann für Cross-Browser-Testing, Cross-Device-Testing, Deep-Visual- sowie funktionales Regressionstesten verwendet werden – je nachdem, was man ignoriert oder eben nicht.

Der Filtermechanismus ist gleichermaßen einfach (angelehnt an die .gitignore-Datei) wie mächtig. So lassen sich einzelne Attribute global oder für bestimmte Elemente filtern sowie einzelne Elemente komplett oder sogar ganze Teilbereiche der Seite ignorieren. Und wem das noch nicht reicht, der kann Filterregeln in JavaScript implementieren und so etwa unterschiedliche URLs mit gleicher Basis oder Positionsunterschiede kleiner fünf Pixel ignorieren.

Ein guter Ausgangspunkt zum Verständnis sind die vordefinierten Filterdateien, die recheck-web mit ausliefert [4]. So ist das Ignorieren der Elementpositionierung in der Regel eine gute Idee. Wenn die Leser mehr darüber erfahren möchten, wie sie ihre recheck.ignore-Datei pflegen oder eigene Filter erstellen können, sollten sie die Dokumentation lesen [5].

recheck-web ist eines der wenigen Golden-Master-basierten Testwerkzeuge. Alternativen sind zum Beispiel Approval Tests [6] und Jest [7]. Das Tool ist kostenlos und Open Source. Es bietet die Möglichkeit, schnell und einfach Tests zu erstellen, die vollständiger und robuster sind als herkömmliche Tests. Da es im Prinzip gerenderte Webseiten (oder Teil davon) miteinander vergleicht, lassen sich damit auch Cross-Browser-Testing, Cross-Platform-Testing und andere Testszenarien realisieren.

Das Geschäftsmodell des Unternehmens hinter recheck-web (ReTest) besteht darin, zusätzliche Dienstleistungen (z.B. zur Speicherung der Golden Master und Reports sowie eine KI zur Generierung der Tests) und eine kommerzielle GUI auf Basis des CLI zur Pflege der Golden Master anzubieten.

Jeremias Rößler
ist promovierter Informatiker, Speaker und Gründer der ReTest GmbH. Sie spezialisiert sich auf die KI-basierte Testgenerierung und stellt dazu das Difference-Testing-Tool recheck als Open Source bereit.
(ane [8])


URL dieses Artikels:
https://www.heise.de/-4598576

Links in diesem Artikel:
[1] https://github.com/retest/recheck-web-example
[2] https://www.heise.de/ratgeber/Difference-Testing-mit-recheck-web-Von-der-Installation-bis-zur-Stabilisierung-4427607.html
[3] https://github.com/retest/recheck-web
[4] https://github.com/retest/recheck/tree/master/src/main/resources/filter/web
[5] https://docs.retest.de/recheck/usage/filter/
[6] https://approvaltests.com
[7] https://github.com/facebook/jest
[8] mailto:ane@heise.de