dynamische Testgenerierung mit Eclat, Randoop und Palus

Quelle : http://geekandpoke.typepad.com

Über die stark verschneiten Feiertage hatte ich, neben dem Ärgernis über vereiste Oberleitungen und dem damit einhergehenden Stromausfällen, ein wenig Zeit gefunden, mich über mögliche Themen für meine Bachelor-Thesis zu informieren und zu belesen. Ein genaues Thema habe ich noch nicht, aber ich denke, dass der Schwerpunkt in der „Sicherung und Erweiterung der Software-Qualität“ liegen wird. Nachdem wir im Projekt die statische Analyse unseres Source-Codes größtenteils und erfolgreich von Sonar erledigen lassen, wird der dynamische Test größtenteils vom (menschlichen) Testmanagement erledigt. Speziell in der Testabdeckung kann hierbei noch einiges „rausgeholt“ werden. Neben diversen wissenschaftlichen Publikationen vom MIT habe ich drei Tools gefunden, die sich speziell mit der Testgenerierung für Java-Anwendungen beschäftigen.

Zum einen ist das Eclat. Eclat ist ein Tool, mit dem man direkt für Java-Klassen JUnit-Tests in Form von Asserts erzeugen kann. Das Finden von Assert-Parameters, in diesem Zusammenhang auch Items genannt, wird mittels des Eclat-Algorithmus‘ realisiert. Und dieser Algorithmus ist genau wie der Apriori-all-Algorithmus ein Verfahren zur Assoziationsanalyse (Data-Mining), um aus großen Datenbeständen assoziativ kleinere Teilmengen herauszufiltern. Mit Apriori-all habe ich ja bereits während meines Aufenthalts in Israel gute Erfahrungen gemacht, wobei Data-Mining, eng verwandt mit dem Machine-Learning, bei Software-Tests letztendlich auch sinnvoll erscheint. Leider wurde ich nach einem kurzen Mailwechsel mit Carlos Pacheco, einem Mitbegründer von Eclat, enttäuscht, da seit 2005 keinerlei Aktivitäten mehr in diesem Projekt gemacht wurden. Nach ein paar Versuchen, das eclat-Eclipse-Plugin mit einer aktuellen Version von Daikon und Chickory zu reanimieren, empfahl er mir stattdessen (sein neues Projekt 🙂 ) Randoop.

Randoop ist ebenfalls ein Tool zur Generierung von JUnit-Tests, wobei bei Randoop Sequenzen von Methoden- und Konstruktoren-Aufrufe mittels Data-Mining erzeugt werden. Diese Sequenzen werden dann dazu genutzt, wie bei Eclat eine Reihe von JUnit-Tests zu erzeugen. Das Besondere hierbei ist jedoch, dass diese JUnit-Tests feedback-directed erstellt werden. Das bedeutet, dass die Tests mit den erzeugten Sequenzen anschließend von Randoop verwendet werden, um während der Ausführung der Tests Bugs im Code „zur Laufzeit“ zu finden. Angenehm hierbei ist, dass die TestValues von Randoop manuell angepasst werden könne, um mehr und speziellere Auswahl bei der Zufallserzeugung von Parametern zu erlauben. Und auch das seit November veröffentlichte Eclipse-Plugin dürfte die Verbreitung und Benutzung beflügeln.

Aufbauend auf Randoop und dem Plume-Projekt, welches inzwischen große Teile des Daikon-Projektes (einer Bibliothek von Eclat) übernommen hat, entstand das Projekt Palus. Palus ist ebenfalls ein automatisierter Test-Generator für Java-Anwendungen. Es verbindet dabei aber die dynamische und statische Programmanalyse insofern, dass der dynamische Teil die Execution-Trace, also die Ausführungs-Spur der Anwendung verwendet, um ein parametrisierbares Aufruf-Sequenz-Modell zu erzeugen. Dabei kann die Execution-Trace auch durch bereits vorhandene Tests erweitert werden. Der statische Teil führt eine Abhängigkeits-Analyse (dependency-analysis) durch und berechnet daraus für jede zu testende Methode eng verbundene Methoden. Sowohl das Sequenz-Modell als auch die Abhängigkeits-Informationen tragen dazu bei, die Test-Generierung zu optimieren und noch mehr mögliche Tests zu erzeugen. Palus rühmt sich nebenbei damit, Fehler und damit fehlende Testfälle in den Quellcodes von Sun und IBM gefunden zu haben.

Da der Support für Eclat eingestellt wurde und ich es nicht geschaft habe, hierbei die Beispiele vollständig nachzuvollziehen und Unit-Tests zu erzeugen, wird das erstmal (leider) außen vor bleiben. Randoop und Palus hingegen werden noch aktiv entwickelt und in meinen ersten Testprojekten eingesetzt fanden sie tatsächlich Fehler, ohne, dass ich für die Projekte einen einzigen Unit-Test schreiben musste. Bei Gelegenheit werde ich diese Beispiele und die zugehörigen Aufrufe in diesen Blog schreiben. Und wenn ich wieder im Büro bin und etwas Luft ist, könnte ich die Tools auch auf unseren Code anwenden und mit unserer der Testabdeckung vergleichen.
Tatsache ist: Das Feld in diesem Teil der dynamischen Analyse ist sehr groß, da auch die Software-Anwendungen und -Erstellungen immer vielfältiger werden. Eine strukturierte und automatisierte Testmethodik im Projekt wird jedoch das menschliche Testmanagement keinesfalls ablösen sondern bestenfalls fundiert unterstützen können. Fehler 40 kann eben nicht von einer Maschine hervorgerufen werden 😉