Modellbasierte Entwicklung von Testspezifikationen Holger Funke HJP Consulting GmbH, Hauptstraße 35, 33178 Borchen holger.funke@hjp-consulting.com Zusammenfassung Das Schreiben und Implementieren von Testspezifikationen auch im Bereich von Chipkarten- Applikationen ist eine zeitintensive und oft auch fehleranfällige Aufgabe. Um diese Aufwände zu reduzieren, muss der bisherige Weg Tests zu beschreiben und zu implementieren verlassen werden, da hier zu große manuelle Anteile vorhanden sind. Basierend auf den Erfahrungen beim Testen des elektronischen Reisepasses und des elektronischen Personalausweises beschreibt der Autor in diesem Beitrag einen alternativen Weg, um beim Erstellen und Umsetzen von Testspezifikationen Zeit zu sparen und die Fehleranfälligkeit zu reduzieren. Mit neuen Techniken und Werkzeugen aus den Bereichen der Modellbasierten Softwareentwicklung und den domänenspezifischen Sprachen ist es möglich, die Spezifizierung und Implementierung von Tests signifikant zu verbessern. Der Autor beschreibt seine Erfahrungen der Nutzung einer domänenspezifischen Sprache um Chipkarten zu prüfen und Testspezifikationen zu erstellen. 1 Einführung und Motivation Mit der immer größer werdenden Komplexität von Chipkartenapplikationen wird auch der Aufwand, der für den Test dieser Applikationen betrieben werden muss, immer größer. In diesem Beitrag soll exemplarisch anhand der Dokumente, die im Rahmen des elektronischen Reisepasses (epass) und des elektronischen Personalausweises (epa oder npa) entstanden sind, eben diese bisherige Vorgehensweise dargestellt und auch ein Lösungsweg gezeigt werden, der eine alternative Vorgehensweise beschreibt. Bisher war das Schreiben und Umsetzen von Testspezifikationen, die die weltweite Konformität der hoheitlichen Dokumente sicherstellen sollen, eine Aufgabe in mehreren Schritten. Als erstes erstellt das Bundesamt für Sicherheit in der Informationstechnik eine erste Version einer technischen Richtlinie, indem ein Autor alle Testfälle in einem Dokument zusammenträgt. Im Falle der Reisepässe und der Personalausweise ist dies bspw. die technische Richtlinie TR-03105 [TR3105]. In diesem Dokument finden sich alle Tests, die für die Datenstrukturen und die Protokolle auf dem Chip relevant sind. Diese erste Version der Richtlinie wird dann anschließend von den Testhäusern bzw. den Herstellern der Testsoftware in ihrer jewei-
2 Titel des Beitrages ligen Applikation umgesetzt. Dazu nehmen sie das Dokument und übertragen manuell Testfall für Testfall in das jeweilige Zielsystem. Gerade in der Anfangsphase einer neuen Richtlinie gibt es einige Änderungen des Dokuments. Bei jeder neuen Veröffentlichung durch das BSI müssen die Hersteller nun ihre jeweilige Umsetzung der Testfälle anpassen bzw. erweitern (siehe Abb. 1). Abbildung 1: Derzeitige Vorgehensweise für Testspezifikationen Wir haben hier also sowohl bei der Erstellung als auch bei der Implementierung der Testspezifikationen einen sehr großen manuellen Anteil. Dies führt zu großen Aufwänden auf beiden Seiten und birgt natürlich auch die Gefahr von Fehlern. Mit zunehmender Komplexität von Chipapplikationen wird diese Vorgehensweise zu aufwändig. Aus diesem Grund soll hier ein möglicher Lösungsweg aus dieser Sackgasse aufgezeigt werden. 2 Alternative Vorgehensweise Wirft man einen Blick in die Komformitätstests aus den technischen Richtlinien in [TR3105], fällt die Struktur aller Testfälle ins Auge. Ein Testfall hat immer den gleichen Aufbau. Er besteht aus den folgenden Elementen: Testcase ID Purpose
Titel des Beitrages 3 Version Profile Pre-Conditions Test Scenario Expected Results. Die TestCase ID beinhaltet einen eindeutigen Bezeichner für jeden Testfall. In Purpose findet sich eine natürlich-sprachliche Beschreibung des jeweiligen Testfalls, und Version beschreibt einen aktuellen Versionsstempel des Testfalls, um die Historie einfacher nachvollziehen zu können. Das Profil eines Testfalls gibt an, welche Charakteristiken ein Chip erfüllen muss, damit dieser Test für ihn relevant ist. In den Pre-Conditions werden die Startparameter definiert, die zu Beginn des eigentlichen Tests erreicht sein sollen. Darüber hinaus bestimmen diese oft den Status, den der Chip für die Ausführung des Tests erlangen soll. Das Test- Scenario bestimmt anschließend den eigentlichen Test, wobei der Test in unterschiedliche Schritte unterteilt ist. Das Ergebnis oder der Zustand jeder dieser Schritte wird in den Expected Results bestimmt. Wie man sofort erkennt, basiert jeder Testfall auf der gleichen Struktur. Man kann jetzt also eine Sprache definieren, die den Autor unterstützt, diese Testspezifikation zu schreiben. Als Anforderung gilt: das Schreiben der Spezifikation muss genauso einfach sein wie mit einem gängigen Office-Werkzeug wie Microsoft Word oder Writer aus dem OpenOffice-Paket. Darüber hinaus muss die Software zum Erstellen der Spezifikation frei verfügbar sein, so dass sie von jedermann leicht eingesetzt werden kann. Der Aufbau eines Testfalls ist einfach: Man kann hier recht einfach eine Grammatik definieren, die einen derartigen Aufbau beschreibt. Diese Grammatik kann als Basis genutzt werden, um Testspezifikationen nach Bauart der TR-03105 zu entwickeln. Mit einer solchen Grammatik im Hintergrund kann ein textuelles Modell geschaffen werden, das die einzelnen Tests beschreibt. Auf diese Art und Weise erhält man ein Modell, in dem man Testspezifikationen beschreibt. Aus diesem Modell sollte allerdings auch immer ein lesbares Dokument erstellt werden, das man verteilen kann und das auf einfache Art und Weise von Menschen gelesen werden kann. Dazu wird das Modell um einen Generator erweitert, der aus der Grammatik und den darauf basierenden Testfällen ein Office-Dokument erstellt, das genauso aufgebaut ist wie die bisherigen Dokumente aus der Reihe der TR-03105. Die Lösung besteht also aus dem Erstellen einer speziellen Sprache, mit der sich der Aufbau eines Testfalls beschreiben lässt. Heutzutage gibt es zahlreiche Entwicklungen im Bereich Modellbasierte Entwicklung. Eine dieser Entwicklungen beschäftigt sich mit der Entwicklung von domänenspezifischen Sprachen, die im folgenden Abschnitt näher erklärt werden sollen. Eine solche domänenspezifische Sprache soll in diesem Kontext geschaffen werden, um zum einen die Testfälle zu beschreiben und um zum anderen darauf aufbauend Generatoren zu nutzen, die diese Testfälle in die jeweilige Sprache des verwendeten Testwerkzeugs transferieren. Auf diese Art und Weise soll der manuelle Anteil, wie er in der oben beschriebenen Vorgehensweise noch existiert, reduziert werden. Abbildung 2 zeigt eine mögliche Variante, wie dieser alternative Weg aussehen kann.
4 Titel des Beitrages Abbildung 2: Modellbasierte Entwicklung einer Testspezifikation 2.1 Domänenspezifische Sprachen Eine domänenspezifische Sprache (Domain Specific Language, DSL) ist im Gegensatz zu einer universell einsetzbaren Sprache auf die Beschreibung eines speziellen Problems beschränkt. Es handelt sich dabei um eine formale Sprache, die für eben diese Domäne entworfen und auch implementiert wird. Als formale Sprache wird in der Informatik eine Sprache bezeichnet, die aus einer bestimmten Menge von Zeichenketten zusammengesetzt wird. Eine formale Sprache eignet sich vor allem für die präzise Beschreibung im Umgang mit Zeichenketten. So können bspw. mit formalen Sprachen komplette Programmiersprachen beschrieben werden. Wegbereitend auf diesem Gebiet waren die Arbeiten von Noam Chomsky, der als Linguist u.a. formale Sprachen und Grammatiken untersucht hat. Mit Hilfe von formalen Sprachen kann man auch die Syntax der natürlichen Sprache definieren, wobei selbstverständlich die formale Sprache im Gegensatz zur natürlichen Sprache eindeutig ist. Regeln für Grammatiken können z.b. folgendermaßen aussehen: <Satz> <Nominalsatz> <Verbalsatz> <Nominalsatz> <Adjektiv> <Nominalsatz> <Nominalsatz> <Nomen> <Nomen> Junge <Adjektiv> kleiner
Titel des Beitrages 5 Im Kontext dieses Beitrags interessieren uns aber vor allem die Definition von Zeichenketten und die Ableitung von speziellen Varianten. Mehr zu formalen Sprachen findet man in [HoUl79]. Beim Entwurf einer domänenspezifischen Sprache versucht man also einen hohen Grad an Problemspezifität zu erreichen, um genau dieses eine anvisierte Probleme zu lösen und kein anderes, das außerhalb dieser Domäne liegt. Dadurch hat man gegenüber den universellen Sprachen (wie z.b. die Programmiersprachen Java oder C) die folgenden Vorteile: Geringere Redundanz Deklarative Beschreibung eines Sachverhalts Weniger technischen Code und Beschränkung auf das eigentliche Problem Bessere Lesbarkeit und einfachere Erlernbarkeit durch geringeren Sprachumfang. Gerade der letzte Punkt, den man in der Informatik auch als End User Development bezeichnet, ist ein wichtiger Punkt. Ähnlich wie Makroprogrammierung in den typischen Office- Softwarepaketen, soll diese Vereinfachung dem Anwender die Hürde nehmen, eigene Erweiterungen umzusetzen und die Software an seine Bedürfnisse anzupassen. Allerdings stehen diesen Vorteilen einer domänenspezifischen Sprache auch einige Nachteile gegenüber. Zum einen bedeutet die Entwicklung einer Sprache für ein spezielles Problem auch, dass für jedes weitere Problem eine neue Lösung bzw. Sprache gefunden werden muss. Zum anderen fehlen bei derartigen Sprachen auch die in universellen Sprachen vorhandenen Sprachstandards und die dazugehörige Literatur. Bei der Entwicklung von DSL muss also darauf geachtet werden, diese Nachteile zu kompensieren, indem man z.b. für die nötige Dokumentation sorgt und bei der Definition der DSL schon auf die Mehrfachverwendung achtet, um zumindest Teile der Sprache auch für andere Domänen zu verwenden. Grundsätzlich ist der Zyklus einer DSL durch drei Phasen beschrieben: 1. Die Definition der Sprache: Das Alphabet und die domänenspezifische Syntax werden definiert und ergeben die Grammatik 2. Das Erstellen von Sätzen: Auf Basis der erstellten Grammatik werden Sätze formuliert, die das Problem beschreiben und konform zur in Schritt 1 erstellten Grammatik sind. 3. Das Auswerten der Sätze: Die einzelnen Sätze aus Schritt 2 werden automatisiert weiterverarbeitet, entweder indem sie in eine weitere DSL transferiert werden oder indem sie in eine generische finale Spezifikation überführt werden. Mit einer domänenspezifischen Sprache haben wir nun also ein Mittel, um einen Testfall als Grammatik zu beschreiben. Für zugrundeliegende Patterns, auf denen DSLs aufsetzen, seien die Bücher von Martin Fowler [Fowl10] und Terence Parr [Parr10] empfohlen. Es fehlt jetzt noch die Möglichkeit, diese Sprache auch zu nutzen und sie um Generatoren zu erweitern. Dazu soll im nächsten Kapitel exemplarisch das Projekt Xtext vorgestellt werden.
6 Titel des Beitrages 2.2 Xtext Xtext ist ein Open-Source-Framework, mit dem man innerhalb kürzester Zeit eine neue DSL erstellen kann. Dazu erhält man automatisch einen Editor, um neue Sätze auf Basis der Grammatik zu erstellen, einen Parser, um diese Sätze gegen die Grammatik zu prüfen, und ein Metamodell, das auf dem Parser basiert. Das Werkzeug Xtext ist Teil des Eclipse Modeling Framework (EMF) und ist im Rahmen der Eclipse Lizenz frei verfügbar. Eclipse selbst ist ursprünglich als Integrierte Entwicklungsumgebung (IDE) erstellt worden, wird aber heute aufgrund seiner Erweiterbarkeit für viele unterschiedliche Entwicklungsarbeiten eingesetzt. Bereits bei der Erstellung der Grammatik wird der Anwender beim Definieren der Regeln durch Xtext unterstützt. Mit einem Editor kann er die Grammatik in der erweiterten Backus- Naur-Form (EBNF) festlegen. Die erweiterte Backus-Naur-Form ist eine Metasprache, die benutzt wird, um kontextfreie Grammatiken zu definieren. Standardisiert ist die EBNF in der ISO/IEC 14977 [ISO97]. Aus der so definierten Grammatik erstellt Xtext anschließend neben dem Parser auch das auf EMF basierende Metamodell. Der Parser wird generiert durch ANTLR. Dabei handelt es sich um einen Parser-Generator, der 1989 von Terence Parr entwickelt wurde. ANTLR steht dabei für ANother Tool for Language Recognition. Nähere Information dazu findet man in [Parr07]. Sowohl der Parser als auch das EMF-Modell können unabhängig von Eclipse verwendet werden. Nachdem Parser und Modell automatisch erzeugt sind, erstellt Xtext für die neue Grammatik einen Editor, der es dem Anwender erleichtert, auf dieser Grammatik zu arbeiten. Der Editor enthält einige Merkmale, die das Arbeiten mit der Grammatik erleichtern. Dies sind u.a.: Code Completion: Bereits während der Eingabe kann der Nutzer kontextsensitiv durch Vorschläge innerhalb der Anwendung unterstützt werden. Schlüsselwörter und Operatoren werden automatisch ergänzt, begonnene Sätze können automatisch beendet werden. Syntax Coloring: Schlüsselwörter, Stringliterale und Kommentare werden farblich im Editor hervorgehoben, so dass der Nutzer diese Merkmale besser erkennen kann. Statische Validierung: Neben der syntaktischen Prüfung führt der Editor auch eigene Checks während der Eingabe durch, so dass auch sehr spezifische Rahmenbedingungen geprüft werden können (z.b. Namenskonventionen). Folding und Navigation: Der erstellte Text kann abschnittsweise mittels Folding eingeklappt werden, so dass der übrige Text besser lesbar ist und das Augenmerk auf die jeweils relevanten Teile gelegt werden kann. Darüber hinaus kann automatisch nach Referenzen und Deklarationen gesucht werden. Diese Features des Editors können beliebig an die Bedürfnisse des Nutzers angepasst werden. So liegt es bspw. in seinem Ermessen, die automatische Ergänzung zu erweitern oder die Validierung strenger auszulegen. Damit die erstellten Sprachen auch ausführbar werden, müssen sie letztlich in die Zielsprache bzw. Zielplattform transformiert werden. Dies geschieht mit Xpand, das ebenfalls Teil des EMF ist. Mit Xpand lassen sich die modellierten Sätze in beliebige Artefakte umwandeln.
Titel des Beitrages 7 3 Testspezifikation als Modell Mit der domänenspezifischen Sprache und dem Framework Xtext verfügen wir nun über das Handwerkzeug, um die oben aufgeführten Ziele zu erreichen. Ein Testfall bzw. die übergeordnete Testsuite lässt sich mit Hilfe einer Grammatik beschreiben. Basierend auf dieser Grammatik kann dann mit Hilfe des mit Xtext automatisch erstellten Editors die eigentliche Testspezifikation erstellt werden. Hier bekommt der Autor der Spezifikation die oben beschriebenen Hilfsmittel zur Verfügung gestellt, die ihm das Schreiben der Tests erleichtern und ihm die Möglichkeit geben, sich auf die eigentlichen Tests zu konzentrieren. Eine Beispielgrammatik für eine TestSuite mit dazugehörigen Testfällen wird im folgenden Kapitel kurz erläutert. 3.1 Beispielgrammatik für Testspezifikation Model: (testsuites+=testsuite)+; TestSuite: 'TestSuite' name=id '{' (purpose+=purpose) (testcases+=testcase)+ '}'; TestCase: 'TestCase' name=id '{' (purpose+=purpose) (reference+=reference) (version+=version) 'Profile' (profile+=profile) (quality+=quality) (preconditions+=precondition)+ 'TestScenario' (testscenario+=testscenario)+ (postconditions+=postcondition)+ '}'; Purpose: 'Purpose' STRING; Reference: 'Reference' STRING; Version: 'Version' STRING; Profile: Profile ("EID" "EPASS"); Quality: 'Quality' ("mandatory" "optional");
8 Titel des Beitrages PreCondition: 'Precondition' STRING; TestScenario: (step+=step) (result+=result); Step: 'Step' STRING; Result: 'Result' STRING; PostCondition: 'Postcondition' STRING; Diese Beispielgrammatik zeigt exemplarisch einen Testfall basierend auf der TR-03105 mit zusätzlichen kleinen Ergänzungen. Zuerst wird das Modell festgelegt, das aus mindestens einer Testsuite besteht. Eine TestSuite wiederum hat eine eindeutige ID, eine Beschreibung (purpose) und enthält mindestens einen Testfall. Der Testfall ist analog aufgebaut mit dem kleinen Unterschied, dass Profile und Quality nur durch die vorgegebenen Werte belegt werden dürfen. Das Testszenario besteht dann wieder aus einzelnen Schritten, zu denen ein definiertes Ergebnis gehört. 3.2 Generatoren für OpenOffice und Testwerkzeuge Mit dem oben erwähnten Xpand kann man jetzt aus dem Modell der Testspezifikation die benötigten Artefakte generieren. Dazu passt man die Erweiterungsregeln in Xpand für die jeweilige Zielplattform an. Der Autor hat für dieses Projekt zwei Generatoren erstellt: der erste erzeugt eine XML-Struktur, die zu einer OpenOffice-Datei zusammengefügt wird und dort mit Writer weiter bearbeitet werden kann. Der andere Generator erzeugt eine XML-Struktur, die einen Testfall für den als Open-Source verfügbaren GlobalTester [Glob11] darstellt. Dieser Testfall beinhaltet alle Informationen aus der Testspezifikation und muss vom Entwickler noch um die benötigten Funktionen erweitert werden, die im jeweiligen Schritt des Testszenarios benötigt werden. Man kann hier natürlich beliebige Generatoren erstellen, die Testfälle für beliebige Zielplattformen erzeugen. 4 Zusammenfassung und Ausblick Der vorgestellte Ansatz hilft in dieser Form bereits beim Erstellen einer Testspezifikation und verbessert den bisherigen Prozess, in dem manuelle Anteile durch automatisierte Vorgänge ersetzt oder erweitert werden. Der Editor bzw. Autor einer Testspezifikation erhält frei verfügbare Werkzeuge, mit denen es ihm erleichtert wird, die Testspezifikation zu erstellen und zu warten, da der Editor speziell auf seine Bedürfnisse zugeschnitten ist und ihm dadurch Möglichkeiten an die Hand gegeben werden, die eine Standard-Textverarbeitung nicht bieten kann. Der nächste Schritt besteht darin, den Anwender auch bei der inhaltlichen Erstellung der Testfälle zu unterstützen. Dazu soll die Grammatik ausgeweitet werden auf eine Sprache, die zur Beschreibung von Tests geeignet ist. Diese Testsprache muss die Möglichkeit bieten, zum einen Kommandos aus den Protokollen abzubilden, zum anderen aber auch die verwendeten
Titel des Beitrages 9 Datenstrukturen abzubilden. Sind die Kommandos und Datenstrukturen erst einmal in einer Grammatik beschrieben, so kann man basierend auf diesen Modellen auch automatisch Testfälle ableiten. Der Editor der Testspezifikation erhält dadurch schon Standardtestfälle für die verwendetet Chipkartenapplikation und kann seinen Fokus auf das Erstellen von protokollspezifischen Tests legen, die man nicht automatisch erzeugen kann, sondern für die man immer noch den Sachverstand eines Experten benötigt. Literatur [BCE+11] [Ecli11] Behrens, Heiko; Clay, Michael; Efftinge, Sven; Eysholdt, Moritz; Friese, Peter; Köhnlein, Jan; Wannheden, Knut; Zarnekow, Sebastian: Xtext User Guide, 2010 Website Eclipse Xtext: www.eclipse.org/xtext [Fowl10] Fowler, Martin: Domain-Specific Languages. Addison Wesley, 2010 [Glob11] [HoUl79] Website GlobalTester: www.globaltester.org Hopcroft, John E.; Ullman, Jeffrey D.: Introduction to Automata Theory, Languages and Computation. Addison Wesley, 1979 [ISO97] International Organization for Standardization (ISO): Information Technology Syntactic meta language Extended BNF, ISO/IEC 14977, 1996 [Parr10] [Parr07] [TR3105] Parr, Terence: Language Implementation Patterns Build your own Domain- Specific and General Programming Languages. The Pragmatic Programmers, 2010 Parr, Terence: The Definitive ANTLR Reference Building Domain-Specific Languages. The Pragmatic Programmers, 2007 Bundesamt für Sicherheit in der Informationstechnik (BSI): Conformity Tests for Official Electronic ID Documents TR-03105, 2008-2010