Blog Testen im Team mit OpenSSL

Testen im Team mit OpenSSL

Im letzten Beitrag zum Thema "Testen im Team" haben wir beschrieben, wie wir eine Umgebung und Verfahren implementiert haben, um SoapUI in einem Team von Testern benutzen zu k├Ânnen.

Neben den Funktionstests an der SOAP-Schnittstelle unseres Testgegenstands sind weitere Tests erforderlich, die die Korrektheit der TLS-Verbindungen verifizieren. Bei einem Embedded System im Gesundheitsbereich ist eine fehlerfreie Implementierung der Verschl├╝sselungsstandards unabdingbar. Entsprechend rigide sind die Anforderungen aus der Spezifikation und entsprechend vielf├Ąltig ist der Detailreichtum der zu testenden Szenarien.

Die hierf├╝r notwendigen Tests sind mit einem Browser nicht sinnvoll durchf├╝hrbar, auch das f├╝r die funktionalen Tests verwendete SoapUI ist nicht geeignet, um einen TLS Handshake Byte f├╝r Byte nachvollziehen zu k├Ânnen. Stattdessen haben wir uns f├╝r die Verwendung von Bash-Skripten in Kombination mit OpenSSL entschieden. Dieses hoch spezialisierte Tool bietet alle Diagnosem├Âglichkeiten, um die geforderten Szenarien nachstellen zu k├Ânnen.

Weiterhin hatten wir ├Ąhnliche Anspr├╝che an unser Vorgehen wie im letzten Beitrag beschrieben:

(1) Die Tests sollten als Regressionstests jederzeit erneut durchf├╝hrbar sein.
(2) Die Tests sollen m├Âglichst unabh├Ąngig vom Arbeitsplatz des Testers funktionieren.
(3) Die Nachvollziehbarkeit der Weiterentwicklung der Tests soll gegeben sein.

OpenSSL ist nicht einfach zu bedienen. Eine Kommandozeile zusammenzustellen, die genau die gew├╝nschte Kombination aus TLS-Levels, Ciphersuites, Truststores und Clientzertifikaten abbildet, ist nicht trivial. Dazu kommen noch unterschiedliche fachliche HTTP-Aufrufe, was die kombinatorische Anzahl der M├Âglichkeiten nochmal steigert.

Die Komplexit├Ąt wurde uns allerdings erst im Laufe der Tests klar, sodass in der Nachbetrachtung eine deutliche Evolution im Vorgehen sichtbar wird. Ein Paradebeispiel f├╝r unser iteratives Vorgehensmodell ÔÇô mit einem Wasserfallmodell w├Ąren wir nicht in der gew├╝nschten Zeit und Qualit├Ąt zum Ziel gekommen.

Zuerst haben wir versucht, einzelne Testf├Ąlle direkt in der Bash mit Aufrufen von "openssl s_client" durchzuf├╝hren. Das ging auch am Anfang recht passabel, allerdings zeigte sich schnell, dass es sinnvoller ist, pro Testfall ein kleines Shell-Skript zu schreiben, um die Wiederholbarkeit der Testf├Ąlle zu gew├Ąhrleisten.

Nach etwa zehn solcher Testf├Ąlle war deutlich erkennbar, dass die Skripte untereinander zu 90% identisch sind. Es lag also nahe, hier ein Refactoring durchzuf├╝hren. Die identischen Elemente aus der OpenSSL Kommandozeile wurden in ein allgemeines Skript  ├╝berf├╝hrt, das wiederum von den testfallspezifischen Skripten mit geeigneten Parametern aufgerufen wird.

In dem Moment, in dem man beginnt in Bash Skripten mit Parametern zu hantieren, ist es sinnvoll, rechtzeitig eine sorgf├Ąltige Behandlung der Kommandozeile einzuf├╝hren: Reihenfolgeunabh├Ąngigkeit der Argumente und eine strenge Syntaxpr├╝fung sind essenziell. Aussagekr├Ąftige ÔÇ×UsageÔÇť Meldungen bei Fehlbedienungen helfen nicht nur anderen Testern, sondern auch einem selbst. Jeder, der schon mal ein komplexes Shell-Skript geschrieben hat, wei├č wie wichtig Dokumentation ist, aber auch wie schwierig es ist, diese Dokumentation geeignet unterzubringen. Unsere Erfahrung in vielen Projekten hat gezeigt, dass vern├╝nftige Usage-Meldungen ein wichtiger Schl├╝ssel dazu sind, dass nicht nur der urspr├╝ngliche Entwickler, sondern auch andere Nutzer gut mit dem Skript umgehen k├Ânnen.

Es galt also, die Skripte so zu gestalten, dass sie die fachlichen Auspr├Ągungen des Tests gut von dem darunter liegenden OpenSSL Aufruf abstrahieren. Wir haben daher folgende Hierarchie an Skripten entwickelt:

testfall_A4516_02d.sh        
├╝bergibt Hostnamen, den HTTP Request als Datei und die Parameter zur Clientauthentisierung

Ruft auf:
prepareConversation.sh | tlsConnect.sh
Syntaxpr├╝fung der Kommandozeile, Preprocessing des HTTP Requests, Parsing und Aufbereitung der Authentisierungsdaten, Aufbau der OpenSSL Kommandozeile

Ruft auf:
openssl s_client
F├╝hrt die Abfrage durch und liefert das Output f├╝r die Dokumentation des Testfalls

Je weiter oben in der Aufrufhierarchie ein Skript steht, desto weniger boilerplate Code enth├Ąlt es und desto fachlicher und testfallbezogener sind die Parameter.

Besonders hervorzuheben ist hierbei die ├ťbergabe des HTTP Requests, der vorbereitet werden muss in Bezug auf Header-Felder wie den Hostnamen und Basic Authentication. Um diese verschiedenen Auspr├Ągungen auf einer Kommandozeile abzubilden, sind die String- und Textersatzverfahren der Bash mit ihren regul├Ąren Ausdr├╝cken hervorragend geeignet.

Auch in diesem Teilprojekt unseres Testvorhabens wurden alle anfallenden Dateien in einem Git Repository abgelegt, sodass die Entwicklungsfortschritte nachvollziehbar waren und die Arbeit im Team aufgeteilt werden konnte.
Damit haben wir zwei der drei gesteckten Ziele erf├╝llt. Offen bleibt die Unabh├Ąngigkeit vom Arbeitsplatz des Testers. Hier haben wir bei n-design Freiheit in der Gestaltung der eigenen Arbeit: Manche Tester verwenden einen Windows-PC, andere bevorzugen Linux. Externe Kollegen greifen auf ihre MacBooks mit OS X zur├╝ck.

Wie bekommt man diese verschiedenen Umgebungen unter einen Hut und wie stellt man sicher, dass alle Teammitglieder dieselben Werkzeuge verwenden? Die L├Âsung lag in diesem Fall in der Verwendung von virtuellen Maschinen, speziell in der Kombination aus VirtualBox und Vagrant. Mit Vagrant lassen sich schnell und einfach virtuelle Maschinen erzeugen, mit Software best├╝cken und wieder zerst├Âren -- alles auf der Basis kleiner und portabler Konfigurationsdateien, die die Erstellung und Konfiguration einer VM beschreiben.

Wir haben eine Standard-VM auf der Basis von Ubuntu 14.04 definiert und so konfiguriert, dass beim Start eine neue Version von OpenSSL gebaut und in der VM installiert wird. So stellen wir sicher, dass wir eine aktuellere Version haben, als Ubuntu im Lieferumfang hat.

Die Konfigurationsdateien f├╝r die virtuelle Maschine lassen sich bequem im selben Git Repository verwalten, in dem schon die Testskripte und alle anderen unterst├╝tzenden Dateien liegen. So k├Ânnen wir nicht nur die Testskripte selbst, sondern die ganze Konfiguration eines Arbeitsplatzes ├╝ber unsere standardisierten Mechanismen an die Tester verteilen. Dadurch erreichen wir Homogenit├Ąt der Arbeitsumgebungen. Das alte Argument "Auf meinem PC funktioniert es aber" zieht so nicht mehr und die Durchf├╝hrung der Tests wird insgesamt portabler, transparenter und nachvollziehbarer.