Im Open Source Bereich gibt es mittlerweile eine Vielzahl von Werkzeugen für die Automatisierung von Akzeptanz-Tests. Dabei gibt es eine Vielzahl verschiedener Konzepte. Das Robot Framework setzt z.B. auf keyword-getriebene Testentwicklung und bietet eine Vielzahl an Werkzeugen und Test-Bibliotheken. FitNesse wiederum organisiert Testfälle in einem eigenen Wiki und bietet die Möglichkeit, Tests direkt aus diesem zu starten. In eine andere Richtung geht JBehave , welches konsequent auf Testbeschreibungen im BDD-Format setzt. Die Testimplementierung erfolgt vollständig in Java. Auf JBehave haben wir hier bereits einen ausführlichen Blick geworfen .
Bei vielen Diskussionen rund um Agile Test-Werkzeuge wird früher oder später Concordion – im allgemeinen positiv – erwähnt. Dabei habe ich allerdings noch niemanden kennen gelernt, der es wirklich produktiv einsetzt. Es ist also höchste Zeit sich ein eigenes Bild zu machen :).
Die Testimplementierung für Concordion erfolgt normalerweise in Java. Es gibt allerdings bereits Portierungen für .NET, Ruby, und Python. Im Folgenden werden wir die Java-Version betrachten, um mein Leben ein wenig leichter zu machen.
Aufgrund der Länge dieses Artikels hier ein kurzer Überblick über die im Folgenden behandelten Themen:
- Download und „Hello World“-Beispiel: Erläuterung der Installation und der Ausführung des im Download enthaltenen Beispiels.
- Testbeschreibung und Testimplementierung: Nach der Ausführung des Beispiels geht es nun daran Concordion wirklich zu verstehen und einen eigenen Test zu implementieren.
- Reporting: Aufbereitung der Testresultate durch Concordion.
- Integration in eine CI-Umgebung: Wie lassen sich in Concordion geschriebene Tests in eine Umgebung für kontinuierliche Integration einbinden?
- Fazit: Wie gut lassen sich Akzeptanz-Tests mit Concordion automatisieren? Für wen eignet sich das Werkzeug?
Download und „Hello World“-Beispiel
Der erste Schritt ist der Download von Concordion. Dies kann entweder über den Download-Bereich erfolgen, oder alternativ auch auf der Getting Started-Seite . Concordion kommt als ZIP-Datei, welche ein Eclipse-Projekt beinhaltet. Es sind alle benötigten Bibliotheken enthalten und auch ein kleines Beispielprojekt. Dieser Blog-Beitrag beruht auf der Version concordion-kickstart-1.4.2.zip.
Um das Projekt in Eclipse einzubinden, erzeuge ich einen neuen Workspace und importiere dann das ausgepackte Concordion-Verzeichnis als neues Projekt in diesen Workspace. Das Ganze sieht dann so aus:
Der erste Blick fällt auf die Ant und Gradle Build-Skripte. Ok, ich bin sicherlich kein großer Maven -Fan, aber es ist ja schon irgendwie der Standard mittlerweile. Aber erstmal abwarten, denn der erste Teststart erfolgt ganz einfach aus Eclipse heraus als JUnit-Test. Hierzu im „specs“-Verzeichnis unter „com.example.specs.greeting“ die Datei „HelloWorldTest“ als JUnit-Test ausführen. Das funktioniert ohne Probleme und in der Konsole wird auch der Pfad zu den Testergebnissen ausgegeben:
C:\DOKUME~1\tja\LOKALE~1\Temp\concordion\com\example\specs\greeting\HelloWorld.html
Successes: 1, Failures: 0
Der generierte Report sieht dann wie folgt aus:
Soweit so gut, doch wie lassen sich nun eigene Tests beschreiben und implementieren?
Testbeschreibung und Testimplementierung
Alle Agilen Test-Tools unterscheiden zwischen der Testbeschreibung und der Testimplementierung. In Concordion erfolgt die Testbeschreibung in Form einer XHTML-Datei. Die Beschreibung bietet hierbei einen hohen Freiheitsgrad und ist nicht auf eine strikte tabellarische Form oder reines BDD-Format beschränkt. Versuchen wir also einen Test zu schreiben für die Java Stack-Implementierung . Hiermit ergibt sich eine gute Vergleichbarkeit mit unserem Artikel über JBehave , bei welchem auch dieses Beispiel genutzt wurde.
Die Syntax für die Testbeschreibung ist sehr eingängig und die folgende Testbeschreibung ist recht schnell erstellt. Es gibt ein paar Kommandos, welche im HTML-Code eingebettet werden um Variablen zu setzen, Methoden aufzurufen und erwartete Ergebnisse zu prüfen. Bei Concordion wird dies als Instrumentierung bezeichnet. Da die zu testende Klasse eine Java API-Klasse ist müssen wir lediglich ein neues Package „com.example.specs.stack“ unterhalb des „specs“-Verzeichnisses erzeugen. In diesem Package erzeugen wir unsere Testbeschreibung in der Datei „Stack.html“ und die zugehörige Implementierung in der Datei „StackTest.java“. Hier gilt es eine implizite Namenskonvention zu beachten, denn die HTML-Datei muss hier den gleichen Namen haben wie die Java-Datei, allerdings ohne „Test“ im Namen und natürlich mit der Endung „.html“.
Für eine gute Vergleichbarkeit mit dem Beispiel aus dem JBehave-Artikel, habe ich mich in der Testbeschreibung für eine BDD-Syntax entschieden. Dies ist aber nicht notwendig, sondern die Syntax kann im Prinzip komplett frei gewählt werden. Relevant für den Test sind letzten Endes die eingebetteten Kommandos. Somit ergibt sich die folgende Testbeschreibung:
Stack Test
1Testing the basic functionality of the Java Stack implementation.
Basic functionality of a Stack
Given an empty Stack
When the string Java is added
And the string C++ is added
And the last element is removed again
Then the resulting element should be Java
Stack search
Given an empty Stack
When the string Java is added
And the string C++ is added
And the string PHP is added
And the element Java is searched for
Then the resulting element should be 3
Die zugehörige Java-Klasse ist denkbar einfach. Diese implementiert die Instrumentierungen in der HTML-Datei, welche durch die Ausdrücke concordion:execute und concordion:assertEquals definiert sind. Damit sieht die Java-Klasse wie folgt aus:
1package com.example.specs.stack;
2
3import java.util.Stack;
4import org.concordion.integration.junit3.ConcordionTestCase;
5
6public class StackTest extends ConcordionTestCase {
7
8 private Stack testStack;
9
10 public void initializeStack() {
11 testStack = new Stack();
12 }
13
14 public void addElement(String element) {
15 testStack.push(element);
16 }
17
18 public void removeLastElement() {
19 testStack.pop();
20 }
21
22 public String stackResult() {
23 return testStack.pop();
24 }
25
26 public int stackSearch(String element) {
27 return testStack.search(element);
28 }
29}
Es ist sehr angenehm, dass hier keine weiteren Klassen notwendig sind, um Verbindungen zwischen den einzelnen Teilen herzustellen. Alle relevanten Funktionalitäten werden durch Vererbung aus der Klasse „ConcordionTestCase“ bereitgestellt und dies im Prinzip für den Entwickler unsichtbar.
Reporting
Der erzeugte Report für einen Testlauf entspricht im Prinzip der Testbeschreibung. Somit liegt es einerseits in der Hand des Testentwicklers wie gut oder schlecht dieser Report aussieht. Auf der anderen Seite gibt es aber auch keine wirklich große Unterstützung beim Reporting oder viele zusätzliche Informationen. Für unser obiges Beispiel wird der folgende Report erzeugt.
Die Begriffe welche mittels Assertions geprüft werden sind im Erfolgsfall grün hinterlegt und somit sofort sichtbar. Im Fehlerfall wird hier in rot der nicht erwartete Wert hervorgehoben.
Integration in eine CI-Umgebung
Vielleicht habe ich hier ja nicht gut genug hingeschaut, aber auf der Concordion-Seite finde ich erstmal gar nichts dazu, wie sich die Tests auf auf der Kommandozeile ausführen lassen. Ich vermute aber mal, dass dies wahlweise über die oben erwähnten Ant– und Gradle-Skripte möglich ist.
Da meine Erfahrung mit Gradle noch geringer ist, als die mit Ant, versuche ich also mein Glück mit letzterem. Und siehe da, es geht alles ganz einfach und funktioniert out-of-the-box. Nach dem Öffnen der build.xml-Datei lässt sich in Eclipse – im Outline-View – der „run tests“-Task auswählen. Dieser führt alle Tests durch und schreibt die Ergebnisse im Workspace in das Verzeichnis „build/concordion-output“.
Hier auch noch die Ausgabe für den Testlauf via Ant. Dies auf Maven umzustellen wäre mal ein gutes Thema für einen weiteren Blog-Beitrag :).
1Buildfile: C:\workspace\concordion\concordion-kickstart\build.xml 2compile: 3 [mkdir] Created dir: C:\workspace\concordion\concordion-kickstart\build\classes 4 [javac] Compiling 3 source files to C:\workspace\concordion\concordion-kickstart\build\classes 5 [copy] Copying 6 files to C:\workspace\concordion\concordion-kickstart\build\classes 6run.tests: 7 [mkdir] Created dir: C:\workspace\concordion\concordion-kickstart\build\test-output 8 [mkdir] Created dir: C:\workspace\concordion\concordion-kickstart\build\concordion-output 9 [junit] Running com.example.specs.greeting.HelloWorldTest 10 [junit] C:\workspace\concordion\concordion-kickstart\build\concordion-output\com\example\specs\greeting\HelloWorld.html 11 [junit] Successes: 1, Failures: 0 12 [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0,234 sec 13 [junit] Running com.example.specs.stack.StackTest 14 [junit] C:\workspace\concordion\concordion-kickstart\build\concordion-output\com\example\specs\stack\Stack.html 15 [junit] Successes: 2, Failures: 0 16 [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0,031 sec 17BUILD SUCCESSFUL 18Total time: 3 seconds
Fazit
Der Einstieg in Concordion wird dem Benutzer sehr leicht gemacht. Das Beispiel im Download-Paket funktioniert reibungslos und das Konzept ist eingängig. Dies natürlich um so mehr, wenn man schon ein paar andere Tools kennt :-). Schwierig wird es sicherlich dann, wenn es darum geht dem Konzept von Concordion zu folgen. Dies legt den Fokus darauf Spezifikationen zu schreiben und keine Skripte. Die Möglichkeit dies zu tun ist aber auch ganz klar eine Stärke des Tools.
Beim Schreiben dieser Spezifikationen hat man einen extremen Freiheitsgrad und die Instrumentierung ist auch sehr einfach. Das gesamte Tool ist recht schlank und ist vom Konzept her ein Stück weit vergleichbar mit JBehave. Die Ausführung im Rahmen einer Continuous Integration Umgebung funktioniert problemlos. Das Reporting ist eher minimalistisch zu nennen. Hier kommt es – wie immer – auf die eigenen Anforderungen an.
Natürlich gibt es noch einiges mehr zu entdecken, aber hoffentlich bietet der Artikel einen guten Einstieg in die Testautomatisierung mit Concordion. Der Einstieg in das Tool ist einfach und bietet kaum Frustmomente. Alles funktioniert wie erwartet. Wer also noch auf der Suche nach einem agilen Testwerkzeug ist sollte durchaus mal einen Blick riskieren.
Weitere Beiträge
von Thomas Jaspers
Dein Job bei codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
Weitere Artikel in diesem Themenbereich
Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog-Autor*in
Thomas Jaspers
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.