Seit November 2017 bin ich bei der viadee Unternehmensberatung AG im Team des Testcenters tätig. Hier testen wir Software für Kunden. Im Detail umfasst dies die Konzeption und Erstellung von Testfällen, das Durchführen der Tests sowie die anschließende Dokumentation. Unsere aktuelle Aufgabe ist das Testen von Batchjobs auf einem Mainframe (IBM z/OS). Dies war für uns ein Novum; wir mussten selbst Herangehensweise, Tools und Durchführungsmethodiken erarbeiten. Zunächst haben wir manuell getestet, was verhältnismäßig lange dauerte und fehleranfällig war. Auch der Ausblick auf Regressionstests -also erneute Tests von Software nach einer Veränderung- erfüllte uns nicht unbedingt mit Freude. Daher haben wir uns dazu entschieden, das Testen der Batchabläufe zu automatisieren. Im Folgendem zeige ich, wie wir ausschließlich mit Open-Source-Mitteln das Versenden von JCLs an den Host und das Warten auf den entsprechenden Returncode, das Herunterladen und Validieren erstellter Artefakte sowie das Überprüfen von Datenbankveränderungen automatisieren konnten.
Ich habe keine Lust, Batchjobs zu testen
Der Ablauf ohne Automatisierung war der folgende:
- Händisches Anpassen der JCL (Job Control Language) – Datei
- Mittels der Ausführung von SQLs die Datenbank in die gewünschte Ausgangslage versetzen
- Sicherung des Datenbankzustands vorher
- Senden der angepassten JCL zur Ausführung an den Host
- Überprüfung der Jobausführung auf Erfolg
- Sicherung des Datenbankzustands nachher
- Herunterladen der durch den Job erstellten Artefakte wie z. B. Protokolle
- Inhaltliche Prüfung der erstellten Artefakte
Der Prozess ohne Automatisierung ist langatmig und monoton. Dadurch sinkt die Konzentrationsfähigkeit und die Validierung der Testergebnisse ist enorm fehleranfällig. Noch dazu sind ein ganzer Zoo an Tools und Hilfsmittel notwendig: Ein Editor zum Anpassen der JCL-Datei, ein SQL-Editor wie z. B. DBeaver, eine Command Shell zum Senden der JCL an den Host sowie zum Herunterladen der erstellten Dateien (Für Zweitgenanntes gerne auch ein FTP-Client wie FileZilla), ein Host Emulator, um das Ergebnis der Jobausführung zu prüfen und ein Textvergleichstool für einen Soll-Ist-Vergleich der erzeugten Dateien.
Da muss es doch einen klügeren Weg geben.
Testautomatisierung von Batchjobs: der Königsweg
Der klügere Weg ist das Automatisieren von Tests. So muss ein Testfall nur einmalig definiert und implementiert werden, welcher dann für verschiedene Varianten des Testfalls durch Variablen angepasst werden kann. Das erzeugt zwar einen erhöhten Erstaufwand; dieser legitimiert sich allerdings bereits durch eine erneute Ausführung des Testdurchlaufs. Ferner ist der Ablauf von Batchtests recht ähnlich, sodass, wenn man einmal eine bestehende Struktur hat, diese nur minimal für den Test anderer Batchabläufe anpassen muss.
Insgesamt werden uns im Testcenter die folgenden Tätigkeiten durch eine Automatisierung abgenommen:
- Befüllung der konkreten JCL-Datei,
- Das Hochladen dieser sowie das Auslesen und die Überprüfung des Returncodes
- Sicherung der Datenbank vor und nach der Ausführung
- Das Herunterladen der durch den Job erstellten Artefakte
- Die Validierung der Datenbankveränderung sowie der Artefakte, entweder im Gesamten oder einzelner Werte
- Erstellung einer Durchführungsdokumentation
Schauen wir uns die genutzten Technologien an.
Host und Java: Starrer Kasten trifft auf flexible Technologien
Die JCL-Datei enthält Angaben wie die Pfade, in welche erzeugte Dateien abgelegt, welche Datenbank genutzt und welches Programm angestoßen werden soll. Dies lässt sich parametrisieren, sodass man ein Template erhält, welches immer wieder genutzt werden kann. Für den Testdurchlauf werden durch die vom Tester angegebenen Parameter sowie dem Template durch das viadee Testframework die tatsächlich zu transferierende JCL-Datei erstellt.
Durch die Nutzung eines JDBC-Treibers können SQL-Dateien auch automatisiert abgeschickt werden, sodass das Herstellen des Ausgangszustands ebenso abgenommen wird. Zeitgleich können die Ergebnisse von Select-Queries in CSV Dateien gespeichert werden. Diese werden anschließend in eine lokale H2 Datenbank geladen, um performant durch Unions Vorher-Nachher-Vergleiche machen zu können. Auf diesem Wege kann geprüft werden, ob sich die gewünschten Einträge verändert haben und vor allem, dass andere nicht modifiziert wurden – ohne Automatisierungsunterstützung eine sehr fehleranfällige Tätigkeit.
Das Herzstück unserer Testautomatisierung bildet jedoch der Umgang mit dem Host. Via FTP kann die JCL an den Host gesendet und aus der Antwort des Hosts die Job ID extrahiert werden. Nach einer definierten Wartezeit wird nach dem Status des Jobs anhand der ID gefragt: Ist der Job nach der angegebenen Zeit nicht abgeschlossen, wird der Job abgebrochen. Eine detaillierte Beschreibung, wie in Java via FTP mit dem Host kommuniziert werden kann, hat IBM hier sowie hier veröffentlicht.
Unter Einsatz eines FTPFileEntryParser wird die Antwort des Hosts in die Klasse JesJob gemappt, die von der Klasse FTPFile erbt. So stehen die entsprechenden Informationen wie Status, Returncode, Jobname und ID objektorientiert zur Verfügung und können im Code weiterverwendet werden.
Via FTPClient können nach Jobabschluss die erstellten Artefakte heruntergeladen werden. Diese liegen dann entweder im Binärformat oder im ASCII Format vor, je nach Parameterangabe bei Aufruf von FTP Get.
Validierung der erstellten Artefakte: Im Ganzen oder Rosinenpicken
Zur anschließenden inhaltlichen Prüfung stehen zwei Möglichkeiten offen: Entweder erstellt man im Vorhinein eine Soll-Datei, die dann durch einen Textvergleich mit der Ist-Datei verglichen wird. Dazu ist ein Download im ASCII Format sinnvoll.
Alternativ kann via XPath auf einzelne Werte zugegriffen und so mit einem Sollwert vergleichen werden. Für die Anwendung von XPath ist eine Konvertierung der heruntergeladenen Dateien notwendig. Dazu sollte als FileType FTP.BINARY_FILE_TYPE gesetzt werden.
Anschließend wird mit der Open Source Library JRecord die Binärdatei in XML konvertiert. Dazu ist das Copybook bzw. die Copystrecke notwendig. In dieser ist vermerkt, von welcher Stelle bis zu welcher Stelle eine Information in der Binärdatei enthalten ist. Beispielsweise, dass die Stelle 10-20 einen Nachnamen enthält. Es dient also als Übersetzungshilfe. Durch die Konvertierung zu einer XML-Datei können beliebige Werte durch XPath extrahiert und mittels eines einfachen Equals gegen den gewünschten Sollwert verglichen werden.
Veni, Vidi, vTF
Im Testcenter der viadee haben wir diesen Möglichkeiten in das bestehende viadee Testframework (vTF) integriert. Es ist eine Inhouse-Entwicklung, sodass wir die Chance hatten, unser eigenes Handwerkszeug selbst auf unsere Anforderungen anzupassen sowie um Features anzureichern und so unseren Testalltag zu vereinfachen.
Das vTF ist ein Testautomatisierungsframework, welches in Java implementiert ist. Es setzt ausschließlich auf Open-Source-Software und ist selbst quelloffen. Die Basis für Testausführungen bilden Testsets, die in Excel geschrieben werden. Einzelne Methoden sind als sogenannte Kommandos gekapselt, die durch Drop-Down Menüs in Excel erreicht werden können. Diesen Kommandos lassen sich auch Parameter übergeben.
Die untenstehende Abbildung zeigt das Kommando „ftpGet“ mit der ID 6001. In den Spalten stehen die erwarteten Parameter. Die mit einem Asterisk gekennzeichneten sind Pflichtfelder. Das heißt, unter Angabe eines Servers („host“), des Nutzernamens und Passworts wird der Inhalt der Datei REMOTE.PFAD.PROTOK in die lokale Datei files/protokoll.txt geschrieben. Bei Kommando 6002 wird eine Binärdatei heruntergeladen; dies ist gesetzt durch die Angabe true in der Spalte IS_BINARY.
Die Credentials stehen selbstverständlich nicht im Klartext im Testset, sondern sind in einem Keepass Container eingebettet und werden ausgelesen. Zur Nutzung von FTP in Java nutzt das vTF die Apache Commons Net Library.
Das Testset – Das Ganze ist mehr als die Summe seiner Teile
Wenn alle Kommandos geschrieben wurden, sieht das gesamte Testset für den fiktiven Testfall 1 wie folgt aus:
Im Testschritt (die grau/braun unterlegten Gruppierungen) 1000 werden die Verbindungen zur Remote Datenbank (ID 1001) und zu der lokalen H2-Datenbank (ID 1002) hergestellt. Die Tabelle „BSP“ wird in Testschritt 2000 initial für den Test beladen. Anschließend wird eine Abfrage an die Tabelle gesendet und die Antwort in bsp_vorher.csv gespeichert. Mit loadCsvSql werden die Inhalte der CSV-Datei in die lokale H2 Datenbank geladen.
Anschließend werden in Testschritt 4000 die JCL-Datei erstellt und ausgeführt. Die Template.jcl Datei enthält den Platzhalter #DBTABLE, der die Beispieltabelle BSP ersetzt wird. Dies vervollständigte Datei beispielBatch.jcl wird dann mit Kommando executeJCL an den Host unter Angabe des Benutzernamens, Passwort, Host und dem akzeptierten Returncode gesendet. In diesem Fall tolerieren wir keinen Returncode größer 0000.
Nach dem erfolgreichen Abschluss des Jobs wird der Zustand der Tabelle BSP erneut abgefragt, das Ergebnis gespeichert und in die H2-Datenbank geladen.
Danach werden in Testschritt 6000 das Protokoll sowie die Nachweisliste heruntergeladen. Diese wird in Testschritt 7000 vom Binärformat mithilfe des Copybooks nachweis.cpy in eine XML-Datei konvertiert. Werfen wir noch einen kurzen Blick in unsere fiktive XML-Datei sowie das Copybook (rechts). Das Copybook gibt an, dass die ID von Stelle 0-6, der Name von 07-47 etc. in der Binärdatei belegt ist.Aus der XML-Datei wird anschließend der Status extrahiert und mittels equalsAlpha gegen den Wert „1“ verglichen. Das Protokoll wird gegen die bereits bestehende Solldatei protokoll_Soll.txt verglichen.
Die Überprüfung der Datenbankveränderungen geschieht mit compareChangesSql. Unter Angabe der beiden Tabellen BSP_VORHER und BSP_NACHHER werden über den Primärschlüssel „ID“ nach Veränderungen gesucht. In unserem Fall erwarten wir eine Datenbankveränderung. Im gegenteiligen Fall würde in der Spalte neben „ID“ noch ein false stehen; dies ist der Parameter „SUCCESS_ON_NO_CHANGE“. Die festgestellten Änderungen werden in der Datei changes_bsp.csv dokumentiert.
Zu guter Letzt werden die Datenbankverbindungen zur Remote- sowie H2 Datenbank geschlossen.
Würde ich es wieder tun?
Testen, auf jeden Fall! Aber nicht händisch. Durch die vielen Tätigkeiten, die mir jetzt abgenommen automatisiert werden, ist meine Arbeit weniger monoton und somit weniger fehleranfällig. Auch sehen wir Regressionstests deutlich gelassener entgegen, da die Testsets als Datei vorliegen, sodass diese mit minimalem Aufwand durchgeführt werden können. Eine Testdurchführungsdokumentation muss ich auch nicht mehr schreiben, die fällt als PDF-Datei am Ende raus. Besser geht’s nicht mehr, oder?