Allure Listener für Screenshots und weitere Anhänge verwenden
Allure Reporting ist eines der beliebtesten Open Source Produkte im Testbereich. Aus gutem Grund! Die Reports aggregieren die benötigten Daten sehr übersichtlich. Die Anbindung an die meisten Testframeworks wie Cucumber, TestNG, Selenide und andere funktioniert in der Regel reibungslos.
Spannend wird es bei Allure nur, wenn es um spezielle Anforderungen geht. Es können Postprocessing Aggregationen von unterschiedlichen Runs sein, aber auch das Anhängen von Dateien (Log Files oder Screenshots…) im Test-Lebenszyklus. Um den letzten Punkt geht es in diesem Artikel.
Problemstellung:
Es wird TestNG mit Appium eingesetzt. Appium wird über einen zweiten RemoteWebDriver angesteuert. Sobald die Appium Tests fehlschlagen, wird eine Fehlermeldung in Allure ausgegeben, aber kein Screenshot in Allure eingefügt.
Das Erstellen und Anhängen vom Screenshot direkt aus dem @Test ist kein großes Problem mit Webdriver + Allure und funktioniert reibungslos mit folgender Zeile:
Allure.addAttachment("Screenshot", new ByteArrayInputStream(((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES)));
Allerdings möchten wir ja nicht an einem bestimmten Punkt Screenshots erstellen, sondern nur dann, wenn der Testfall fehlschlägt. Und das hat sich als problematischer rausgestellt, als am Anfang gedacht.
Lösungsansatz #1: versucht und gescheitert…
Im ersten Versuch wurde ganz einfach versucht, einen TestNG Listener zu verwenden. Durch Implementierung vom Interface ITestListener und Ausimplementierung der passenden Methode (in diesem Fall z.B. onTestFailure) können wir uns an einen bestimmen Zeitpunkt der Testausführung einklinken und benötigte Aktionen ausführen:
public class TestNgListener implements ITestListener { @Override public void onTestFailure(ITestResult result) { // Deine Aktionen hier... } }
Anschließend wird der Listener entweder über Annotation oder XML Datei verknüpft und sollte theoretisch gehen. Aber nur theoretisch… nun kommt das Problem: Screenshot wird erstellt und unter allure results Verzeichnis angezeigt. Aber es erscheint nicht im Report. Und Informationen, die nicht im Report erscheinen, sind bekanntermaßen nicht so hilfreich…
Lösung:
Nach einer langen Suche nach der Ursache, war die Lösung (wie so oft…) auf einer GitHub Seite versteckt. Und zwar hier: https://github.com/allure-framework/allure-java/issues/444
Kurze Zusammenfassung: Es gibt keine Garantie, dass TestNG onTestFailure vor dem Schließen des Allure Kontextes ausgeführt wird, daher Finger weg von TestNG Listener und lieber AllureLifeCycle Listener verwenden.
Die Implementierung selbst ist ähnlich wie vom TestNG Listener und ist schnell erledigt:
public class AllureListener implements TestLifecycleListener { public static RemoteWebDriver driver; @Override public void beforeTestStop(TestResult result) { if (result.getStatus() == Status.FAILED || result.getStatus() == Status.BROKEN) { if (driver != null) Allure.addAttachment(result.getName(), new ByteArrayInputStream(((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES))); } } }
Eine Besonderheit sollte lediglich zum driver angemerkt werden. Hier wurde der statische Driver verwendet. Das kann natürlich eleganter mit ThreadLocal umgesetzt werden.
Jetzt wird es tricky. Damit die auch ausgelöst wird, muss diese Klasse unter resources/META-INF/services/<listener-full-package-path> abgelegt werden. In meinem Fall gibt es also nu eine Datei „resources/META-INF/services/io.qameta.allure.listener.TestLifecycleListener“ mit dem Inhalt
utils.AllureListener
Es können aber natürlich in der gleichen Weise sämtlichen anderen LifecycleListener implementiert werden. Eine Liste der Listener kann hier gefunden werden: https://github.com/allure-framework/allure-java/tree/master/allure-java-commons/src/main/java/io/qameta/allure/listener
Begeisterter Entwickler, Trainer und Berater zu allem Themen rund um agile Softwareentwicklung, Softwarequalität und Testautomatisierung.
Gründer und Geschäftsführer der Firma SimplyTest GmbH
Danke für diesen Artikel. Es hat mich 2 Tage gekostet, herauszufinden, wie man die Methode überschreibt.
Bietet ihr auch Schulungen für Selenium und ähnliche Themen an?
Hallo Paul,
freut mich, dass der Artikel dir helfen konnte! Ist immer schön zu hören, dass der Erstellungsaufwand nicht umsonst war 🙂
Wir bieten mit unserem Unternehmen Schulungen zu Selenium, Playwright, Cypress und anderen Testframeworks an. Schaue dich gerne auf unserer Seite um: https://simplytest.de/training/selenium-testautomatisierung-schulung/
Danke dir und viele Grüße,
Waldemar