Eleganter zum einfachen Report über Jenkins-Testdurchführung

2.3.2020

Im Blog Einfacher Testreport aus Tosca über Jenkins-Testdurchführung habe ich in Form einer ersten Version beschrieben, wie sich mit einfachen Mitteln ein grundlegender Testreport aus den Resultaten der Testdurchführung mit Jenkins erstellen lässt. Die inzwischen gesammelte Erfahrung zeigt, dass der dort beschriebene Ansatz sich in den meisten Fällen als nicht genügend effizient erweisen dürfte. Die Verwendung von Tosca-Testfällen zur Report-Erstellung erfordert verhältnismässig viel Zeit und die Vorgehensweise skaliert nicht. Denn der Aufwand zur Implementierung, Wartung und Durchführung steigt mindestens linear mit der Anzahl an Testfällen, die im Report zu berücksichtigen sind. Zunächst angedacht wurde eine andere Art des Auslesens der relevanten Daten aus den XML-Dateien sowie die Verwendung von XML-Modulen in Tosca. Im weiteren Verlauf hat sich gezeigt, dass der Umweg über Tosca nicht erforderlich ist. Im Folgenden lege ich dar, wie sich derselbe Testreport deutlich effizienter mittels eines PowerShell-Skripts erzeugen lässt.

1. Allgemeines

Aus Gründen des Aufwands und des Zwecks erfolgt die Reporterstellung schneller, wenn dazu keine Tosca-Testfälle erforderlich sind. Stattdessen erfolgt der Prozess zur Erstellung eines Testreports wie in Abb. 1 dargestellt.

Transformationsprozess der XML-Resultatdatei in einen HTML-Testreport
Abb. 1: Transformationsprozess der XML-Resultatdatei in einen HTML-Testreport

Die XSL-Transformation der Jenkins-Resultatdateien vom XML- ins CSV-Format erfolgt sequentiell mittels eines PowerShell-Skripts, das am Ende der Testdurchführung ausgeführt wird. Aus diesen Rohdaten wird schliesslich ein Testreport im HTML-Format generiert.

2. Erstellung des Testreports im CSV-Format

Eine beispielhafte XML-Datei als Resultat der Jenkins-Testdurchführung sieht wie folgt aus (vgl. Listing 1):

Listing 1: Beispielhafte Jenkins-Resultatdatei im XML-Format

Die relevanten Daten werden jeweils aus dem Beginn des Elements <testcase> extrahiert, und zwar aus diesem Teil:

testcase name=“Finanzieren Smoketests – 01_Grundstück erfassen“ time=“168.5116337″ timestamp=“2020-02-10T16:13:05.6008759+01:00″ log=“+ Passed …

Der XML-Transformation ins CSV-Format liegt das folgende XSL-Stylesheet zugrunde (vgl. Listing 2):

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="text"/><xsl:template match="/"><xsl:for-each select="testsuites/testsuite/testcase"><xsl:value-of select="@name"/><xsl:text>;</xsl:text><xsl:choose><xsl:when test="@timestamp = ''"><xsl:text>Nicht ausgeführt;</xsl:text></xsl:when><xsl:otherwise><xsl:value-of select="substring(@timestamp,0,11)"/><xsl:text>&#x20;</xsl:text><xsl:value-of          select="substring(@timestamp,12,8)"/><xsl:text>;</xsl:text></xsl:otherwise></xsl:choose><xsl:choose><xsl:when test="not(@log)"><xsl:text>--&#xD;&#xA;</xsl:text></xsl:when><xsl:otherwise><xsl:value-of select="substring(@log,3,6)"/><xsl:text>&#xD;&#xA;</xsl:text></xsl:otherwise></xsl:choose></xsl:for-each></xsl:template></xsl:stylesheet>

Listing 2: XSL-Stylesheet für die XML-Transformation

Mittels des folgenden PowerShell-Skripts werden aus dieser Jenkins-Resultatdatei im XML-Format die für den Testreport relevanten Daten extrahiert und im CSV-Format gespeichert (vgl. Listing 3). Zugrunde liegt dabei ein ähnliches Skript, das unter XSL Transformation von XML-Dokumenten per PowerShell beschrieben wird. Aufgelistet sind nur die inhaltlich relevanten Funktionen (z.B. ohne Pfadprüfung oder Fehlerbehandlung).

# XML-Transformation mit einer XSLT-Datei ins CSV- und HTML-Format# Skript-Aufruf: *.ps1 [XML-QuellDatei(en)] [XSLT-Datei] [Fachgebiet]# Parameterinitialisierungparam (  $xml = @("D:\Tosca\Resultat\Jenkins\Finanzieren\Eigenheim_Resultat.xml","D:\Tosca\Resultat\Jenkins\Finanzieren\    Smoketests_Resultat.xml"),  $xslt = "D:\Tosca\Resultat\XSL\XSL-Stylesheet.xsl",  $area = "Finanzieren" )# Funktion für die XML-Transformationfunction XML-Transformation($xml, $xsltFile, $area){  # Zeitstempel erstellen  $timestamp = ([datetime]::now).tostring("yyyy-MM-dd HH-mm")  # Temporäre CSV-Ausgabedatei definieren  $csv = "D:\Tosca\Resultat\XSL\Testreport.csv"  # Resultatdateien mit Pfad initialisieren  $resultCSV = "D:\Tosca\Resultat\XSL\Report_" + $area + "_$timestamp.csv"  $resultHTML = "D:\Tosca\Resultat\XSL\Report_" + $area + "_$timestamp.html"  # Header in die CSV-Datei schreiben  Add-Content -Path $resultCSV -Value 'Testfall;Zeitstempel;Testergebnis'  # Array der XML-Inputdateien bearbeiten  ForEach ($xmlFile in $xml) {    $xmlFile = resolve-path $xmlFile    # XSL-Objekt erstellen    $script:xslt = new-object system.xml.xsl.xslcompiledtransform    $script:xslt = new-object system.xml.xsl.xsltransform    $xslt.Load($xsltFile) # Xslt-Datei laden    $xslt.Transform($xmlFile, $csv) # XSLT-Transformation ausführen    # Ergebnis in Resultatdatei anhängen    Add-Content -Path $resultCSV -Value (Get-Content $csv) -Encoding UTF8  }  # Temporäre Ausgabedatei löschen  Remove-Item $csv}# Funktionsaufruf zur XML-TransformationXML-Transformation $xml $xslt $area

Listing 3: PowerShell-Skript zur XSL-Transformation ins CSV-Format

Die folgenden Parameter können beim Skriptaufruf übergeben werden:

-xmlJenkins-Resultatdateien im XML-Format als kommagetrennte Liste-xslPfad zur XSLT-Stylesheet-Datei (optional, wenn im Skript hinterlegt)-areaFachbereich (z.B. Finanzieren, Zahlungsverkehr)

Ein weiterer Parameter könnte dazu verwendet werden, die Ablage der generierten Reportdateien zu bestimmen.

Das Ergebnis im CSV-Format sieht beispielsweise so aus:

Finanzieren Smoketests – Grundstück erfassen;2020-02-10 16:13:05;Passed
Finanzieren Smoketests – Versicherung erfassen;2020-02-10 16:16:58;Passed
Finanzieren Smoketests – Finanzierung zusammenstellen;2020-02-10 16:19:37;Failed
Kreditportfolio überprüfen;Nicht ausgeführt;–

3. Transformation ins HTML-Format

Da der Import ins binäre Format von Microsoft Excel kein einfacher Prozess ist und der Testreport primär über das reine Testergebnis informieren soll, wird dafür das HTML-Format eingesetzt. Wie im vorherigen Blog erwähnt, liesse sich der Excel-Import mittels Tosca durchführen. Darauf wird hier jedoch verzichtet.
Die Transformation der CSV-Rohdaten in einen HTML-Testreport erfolgt mit dem zweiten Teil des PowerShell-Skripts am Ende der Funktion zur XML-Transformation (vgl. Listing 4; reduziert auf die wesentlichen Inhalte):

 $head = @"<title>Testreport</title><meta charset="utf-8"><style type="text/css">      BODY{background-color:#FFFFFF;color:black;font-family:Arial,sans-serif;font-size:14px;margin:25pt;}      TABLE{border-width:2px;border-style:solid;border-color:black;border-collapse:collapse;}      TH{border-width:1px;padding:8px;border-style:solid;border-color:black;background-color:#D5D8DC;         font-size:18px;text-align:left;}      TD{border-width:1px;padding:8px;border-style:solid;border-color:black;background-color:#F9F9F9;}</style><script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js"></script><script type="text/javascript">      jQuery(document).ready(function(){      jQuery('td:contains("Passed")').css('background-color','#2ECC71');      jQuery('td:contains("Failed")').css('background-color','#EC7063');      jQuery('td:contains("--")').css('background-color','#D0D3D4');      });</script>"@    $body = "<h1>Testreport $area</h1>"    Import-Csv -Delimiter ";" -Path $resultCSV -Encoding UTF8 | ConvertTo-Html -Head $head -Body $body | Out-File      $resultHTML

Listing 4: PowerShell-Skript zur Erstellung des HTML-Testreports aus der CSV-Datei

Der Testreport im HTML-Format lässt sich beispielsweise so wie in Abb. 2 gestalten:

Testreport im HTML-Format

Abb. 2: Testreport im HTML-Format

4. Jenkins-Konfiguration

Die Konfiguration für die Jenkins-Testdurchführung ist in Listing 5 dargestellt:

pipeline {    agent any    options {       timeout(time: 120, unit: 'MINUTES')    }    parameters {        choice(name: 'ENV', choices: ['CT', 'INT'], description: 'Selektiere Environment')    }    environment {        TRICENTIS_CI_HOME = 'C:\\Program Files (x86)\\TRICENTIS\\Tosca Testsuite\\ToscaCommander\\ToscaCI\\Client'        TRICENTIS_CI_CONFIG = 'D:\\Tosca\\Konfigurationen\\'        TRICENTIS_CI_ENVIRONMENT = "${params.ENV}"        JUNIT_RESULT_FILE = 'D:\\Tosca\\Resultat\\Jenkins\\Finanzieren'    }    stages {        stage('Kreditantrag erstellen') {            steps {                parallel("Eigenheim": {                    echo "Starten der Tosca-Tests für Finanzierung: Eigenheim"                    bat label: 'Eigenheim', script: '"%TRICENTIS_CI_HOME%\\ToscaCIClient.exe" -t junit -r "%JUNIT_                      RESULT_FILE%\\Eigenheim_Resultat.xml" -m distributed -c "%TRICENTIS_CI_CONFIG%\\%TRICENTIS_CI                      _ENVIRONMENT%_Finanzieren_Eigenheim.xml"'                }                )            }        }        stage('Prozessneutrale Tests') {            steps {                parallel("Smoketests": {                    echo "Starten der Tosca-Tests für Finanzierung: Smoketests"                    bat label: 'Smoketests', script: '"%TRICENTIS_CI_HOME%\\ToscaCIClient.exe" -t junit -r "%JUNIT_                      RESULT_FILE%\\Smoketests_Resultat.xml" -m distributed -c "%TRICENTIS_CI_CONFIG%\\%TRICENTIS_                      CI_ENVIRONMENT%_Finanzieren_Smoketests.xml"'                }                )            }        }        stage('Testreport') {            steps {                parallel("Testreport": {                    echo "Starten des Testreports"                    bat label: 'Testreport', script: '"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.                      exe" -ExecutionPolicy Bypass -Command "D:\\Tosca\\Resultat\\XSL\\XML-Transformation.ps1" -xml                      "%JUNIT_RESULT_FILE%\\Eigenheim_Resultat.xml,%JUNIT_RESULT_FILE%\\Smoketests_Resultat.xml"                      -area "Finanzieren"'                }                )            }        }    }}

Listing 5: Beispielhafte Jenkins-Konfiguration

5. Versand per E-Mail

Mit PowerShell lässt sich diese Reportdatei im HTML-Format als Anhang automatisch an die gewünschten Empfänger versenden (vgl. Emails mit PowerShell versenden). Der Testreport kann auch direkt in die E-Mail integriert werden, wenn das HTML-Format zugelassen ist. Mit der Version zur HTML-Generierung in Listing 4 geht dabei die farbliche Hervorhebung des Testergebnisses verloren, da die Ausführung von JavaScript bei E-Mails im HTML-Format aus Sicherheitsgründen meist deaktiviert ist. Dafür können bei der Umwandlung des CSV-Reports in HTML-Code in der Spalte «Testergebnis» CSS-Klassen für die visuelle Unterscheidung eingesetzt werden. Die Skript-Definitionen mit den jQuery-Funktionen sind dann nicht erforderlich. Das entsprechend angepasste Skript findet sich in Listing 6:

 $head = @"<title>Testreport</title><meta charset="utf-8"><style type="text/css">      BODY{background-color:#FFFFFF;color:black;font-family:Arial,sans-serif;font-size:14px;margin:25pt;}      TABLE{border-width:2px;border-style:solid;border-color:black;border-collapse:collapse;}      TH{border-width:1px;padding:8px;border-style:solid;border-color:black;background-color:#D5D8DC;         font-size:18px;text-align:left;}      TD{border-width:1px;padding:8px;border-style:solid;border-color:black;background-color:#F9F9F9;}      TD.passed {background-color:#58D68D}      TD.failed {background-color:#EC7063}      TD.unexecuted {background-color:#D0D3D4}</style>"@    $body = "<h1>Testreport $area</h1>"    Import-Csv -Delimiter ";" -Path $resultCSV -Encoding UTF8 | ConvertTo-Html -Head $head -Body $body | ForEach      { if ($_ -like "*<td>Passed*") {$_ -replace "<td>Passed", "<td class=`"passed`">Passed"} elseif ($_ -like      "*<td>Failed*") {$_ -replace "<td>Failed","<td class=`"failed`">Failed"} else {$_ -replace "<td>--",      "<td class=`"unexecuted`">--"}} | Out-File $resultHTML

Listing 6: Angepasstes PowerShell-Skript zur Erstellung des HTML-Testreports aus der CSV-Datei

Eine andere Option könnte der Versand einer E-Mail über ein Jenkins-Plugin sein, nachdem der Testlauf (resp. Build) ausgeführt worden ist. Diese Variante wurde jedoch nicht weiter geprüft, da sich der Prozess mit der gewählten Vorgangsweise direkter steuern lässt.

Das Passwort für den Zugang zum Mailserver sollte verschlüsselt abgelegt werden. Dies kann in PowerShell mit dem Code in Listing 7 erfolgen:

$KeyFile = "C:\Temp\AES256.key"$PasswordFile = "C:\Temp\Passwort.txt"$Password = "Passwort"# Schlüsseldatei mit AES-256 erzeugen$CryptoKey = New-Object Byte[] 32[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($CryptoKey)$CryptoKey | out-file $KeyFile# Passwort verschlüsseln$CryptoKey = Get-Content $KeyFile$SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force$SecurePassword | ConvertFrom-SecureString -key $CryptoKey | Out-File $PasswordFile

Listing 7: Erzeugung eines verschlüsselten Passwortes in PowerShell

Der Testreport kann im Hauptteil der E-Mail mitgesandt werden (vgl. Listing 8 – reduziert auf die wesentlichen Inhalte, ohne Fehlerbehandlung).

# Zugangsdaten$KeyFile = "C:\Temp\AES256.key"$PasswordFile = "C:\Temp\Passwort.txt"$MailUser = "Benutzername"# SMTP-Einstellungen$PSEmailServer = "mail.example.com"$smtpFrom = "absender@example.com"$smtpTo = "empfaenger@example.com"$messageSubject = "Testreport " + $area$messageBody = (Get-Content ".\Report_Finanzieren_2020-02-10 16-32.html" | Out-String)# Zugangsdaten erzeugen$CryptoKey = Get-Content $KeyFile$creds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $MailUser, (Get-Content  $PasswordFile | ConvertTo-SecureString -Key $CryptoKey)# E-Mail versendenSend-MailMessage -Credential $creds -From $smtpFrom -To $smtpTo -Subject $messageSubject -Body $messageBody  -BodyAsHtml -Encoding ([System.Text.Encoding]::UTF8) -port 587 -UseSsl

Listing 8: Automatischer E-Mail-Versand mittels PowerShell

Abhängig von der Konfiguration der konkreten Umgebung ist für Send-MailMessage anstelle der letzten beiden Parameter auch nur -port 25 zu verwenden, z.B. auf dem Jenkins-Server.

5. Verwendung von Jenkins-Plugins

Zu prüfen wäre der Einsatz von Jenkins-Plugins für denselben Zweck der Reportgenerierung und -verteilung basierend auf den XML-Resultatdateien, z.B. HTML Publisher oder Test Results Aggregator. Abhängig vom genauen Verwendungszweck erlaubt die hier beschriebene Vorgehensweise jedoch eine gezieltere Verwendung, indem die Konfiguration leichter oder überhaupt erst anzupassen ist (z.B. beim Versand von E-Mail-Anhängen).

6. Fazit

Diese Darlegung hat gezeigt, wie sich ein Report über die Durchführung von Tests mit Jenkins in wenigen Sekunden erstellen lässt. Im Vergleich zum Einsatz von Tosca-Testfällen erfolgt die Reportgenerierung in einem Bruchteil des vorherigen Zeitbedarfs. Der Konfigurationsaufwand ist deutlich geringer, insofern nicht mehr pro sachlichem Testfall Strukturen zu definieren sind, sondern nur noch einmal pro Fachgebiet und entsprechend der Gliederung der Jenkins-Resultatdateien. Diese Art der Reporterzeugung erlaubt einen vielseitigeren Einsatz. Um neu hinzugekommene Testfälle zu berücksichtigen, sind bei Bedarf nur die Jenkins-Konfigurationsdateien anzupassen. Zudem ist die Verteilung per E-Mail ein effizienter Weg zur direkten Information der relevanten Kreise.

Trainings zu diesem Thema

Alle anzeigen
No items found.

Wir sind bereit für Ihren nächsten Schritt!

Sie möchten unsere Expertise nutzen und technologische Innovationen umsetzen?

Diese Webseite
verwendet Cookies

Cookies werden zur Benutzerführung und Webanalyse verwendet und helfen dabei, diese Webseite zu verbessern. Sie können hier unsere Cookie-Erklärung anzeigen oder hier Ihre Cookie-Einstellungen anpassen. Durch die weitere Nutzung dieser Webseite erklären Sie sich mit unserer Cookie-Richtlinie einverstanden.

Alle akzeptieren
Auswahl akzeptieren
Optimal. Funktionale Cookies zur Optimierung der Webseite, Social-Media-Cookies, Cookies für Werbezwecke und die Bereitstellung relevanter Angebote auf dieser Website und Websites Dritter sowie analytische Cookies zur Verfolgung von Website-Zugriffen.
Eingeschränkt. Mehrere funktionale Cookies für die ordnungsgemässe Anzeige der Website, z. B. um Ihre persönlichen Einstellungen zu speichern. Es werden keine personenbezogenen Daten gespeichert.
Zurück zur Übersicht

Sprechen Sie mit einem Experten

Haben Sie eine Frage oder suchen Sie weitere Informationen? Geben Sie Ihre Kontaktinformationen an und wir rufen Sie zurück.

Vielen Dank. Wir haben Ihre Anfrage erhalten und werden uns im angegebenen Zeitraum bei Ihnen melden.
Oops! Something went wrong while submitting the form.