Unit Tests mit dem Team Developer: TDUnit

Motivation

Wie wahrscheinliche viele Entwickler, die mit dem Team Developer von Unify (Gupta / Centura) arbeiten, stehen wir in unserer Firma vor der Aufgabe, die bestehende TD-Applikation auf die Version 5.x bzw. 6.x der Entwicklungsumgebung anzuheben. Zentrales Thema für uns ist „Unicode“ und zwar deshalb, weil wir aus (historischen) Performance-Gründen etliche externe C-Bibliotheken geschrieben hatten, die u.a. String-Verarbeitung durchführen. Wir stehen also vor der Wahl, die C-Bibliotheken Unicode-fähig zu machen oder sie im Team-Developer nachzuprogrammieren. Wir haben uns für die zweite Option entschieden. Problem dabei: Wie stellt man sicher, dass die über 100 neu zu schreibenden Funktionen dasselbe tun, wie ihre Vorgänger?

Unit Tests

Ein Blick über den Tellerrand zeigt, dass man in anderen Programmiersprachen (Java, .NET) beim Thema Qualistätssicherung längst weiter ist. Dort ist es – zumindest in größeren Projekten – üblich, zusätzlich zum eigentlichen Programmcode sogenannte Unit Tests zu schreiben. Bei meinen Recherchen waren für mich v.a. zwei Quellen sehr hilfreich: Das Buch The Art of Unit Testing: Deutsche Ausgabe (mitp Professional) von Roy Osherove, sowie das dort beschriebene Unit Testframework NUnit für Visual Studio.

Eine zugegeben sehr verkürzte und persönliche Darstellung der Unit Test Methode:

Was sind Unit Tests?

  • Unit Test ist eine von mehreren Komponenten der Software-Qualitätssicherung.
  • Unit Tests testen einzelne Funktionen des Produktionscodes möglichst isoliert.
  • Unit Tests können jederzeit und auch in ferner Zukunft aufgerufen werden.
  • Unit Tests können automatisiert aufgerufen und ausgewertet werden.
  • Unit Tests sind schnell.

Was ist ein Unit Test Framework?

  • Es unterstützt den Entwickler so gut wie irgend möglich beim Schreiben und Ausführen von Unit Testfunktionen.

Warum sollte man Unit Tests schreiben?

  • Um jetzt sicherzustellen, dass eine bestimmte Funktion tut was sie soll.
  • Um in Zukunft sicherzustellen, dass eine bestimmte Funktion immer noch tut was sie soll.
  • Damit man bei der Pflege von komplexer Software Zeit spart.

Unit Testframework

Nun kann man Unit Tests im Prinzip auch ohne ein unterstützendes Framework schreiben – und im einen oder andere Fall hat das sicher jeder TD-Entwickler auch schon mal gemacht. Die Akzeptanz für einen „flächendeckenden“ Einsatz dieser Methode dürfte im Entwickler-Team jedoch gegen Null tendieren. Es muss also ein Unit Testframework für den Team Developer her. Leider konnte ich trotz intensiver Recherche kein einziges Unit Testframework für den TD finden. Ich musste also selbst eines erstellen.

Das Ziel war, unser Entwicklerteam so gut wie möglich beim Schreiben von Unit Tests zu unterstützen. Des weiteren habe ich mich, so gut es ging, am bewährten NUnit orientiert. Heraus kam TDUnit, ein Unit Testframework für den Team Developer.

Im Detail werden mit TDUnit folgende Anforderungen erfüllt:

  • Der Entwickler muss lediglich die Testfunktion erstellen.
  • Er muss die Testfunktion NICHT selbst aufrufen. TDUnit erkennt Testfunktionen eigenständig.
  • Ein Set von vorgefertigten Assert-Funktionen hilft, einfache und verständliche Tests zu schreiben. Einzeiler sind in vielen Fällen möglich.
  • Die Protokollierung erfolgt automatisch.
  • Hält man sich an sinnvolle Benennungskonventionen, kann in den allermeisten Fällen auf eine selbstgeschriebene Nachricht für die Protokollierung verzichtet werden.
  • Debugging des Test- und Produktivcodes im Einzelschrittmodus ist ohne weiteres möglich

Erste Praxistests zeigen eine gute Akzeptanz im Entwicklerteam.

TDUnit

Zunächst benötigt man eine .apt-, .app- oder .apl-Datei mit Produktiv-Code. Die Datei muss komplierbar sein. Nennen wir sie Sample.app. Die zu testende Funktion ist im Beispielt eine Internal Function. (Im derzeitigen Testframework können Internal Functions, Functional Classes und External Functions getestet werden. Funktionen innerhalb von Dialogen und Form-Windows sind derzeit noch nicht (ohne weiteres) testbar).

Als nächstes sollte eine leere SampleTest.app-Datei erstellt werden. Zwei Librarys sind einzubinden: Das Testframework TDUnit.apl und die zu testende Produktiv-Datei, in unserem Fall Sample.app.

In der Test-Datei muss dann eine Functional Class erstellt werden. Drei Konventionen sind dabei einzuahlten: 1) Sie muss von _UnitTestBase abgeleteitet werden. 2) Der Name der Klasse muss auf „Tests“ enden also z.B. InternalFunctionsTests. 3) Die Funktion GetContext() muss überschrieben werden. Inhalt muss genau eine Codezeile sein: Return SalContextCurrent()

Die eigentlichen Tests werden als Funktionen innerhalb der gerade erstellten Klasse geschrieben. Jede Testfunktion muss eine AssertXXX-Funktion enthalten. Für die Benennung der Testfunktion gilt die Konvention: „Name der zu testenden Funktion“_“Beschreibung des Tests“_“Erwartetes Verhalten“. In der SampleApp z.B. so: Function: Calculator_EmptyString_Zero.

Ausgeführt wird der Test über das Menü Debug/Go oder mit F7. Es erscheint das Testrunner-Window und alle vorhandenen Tests werden automatisch ausgeführt. Ist eine Testfunktion in Ordnung – dh. die Assert-Funktion bestätigt das erwartete Verhalten – wird sie im Testrunner grün angezeigt anderenfalls rot.

Das Ergebnis sieht dann so aus:

Downloads

TDUnit ist mit dem Team Developer 3.1 geschrieben. Die Zip-Datei enthält das Framework (TDUnit.apl), sowie eine SampleApp mit Tests. Ebenso eine ausführlichere PDF-Doku.

TDUnit.zip
TDUnit Dokumentation

Über Feedback würde ich mich freuen.

Advertisements

Über thomasuttendorfer
Ich bin Entwicklungsleiter bei der Softwarefirma [ frevel & fey ] in München. Wir entwickeln Business-Software für Verlage und verwenden dafür den Gupta Team-Developer sowie Visual Studio.

6 Responses to Unit Tests mit dem Team Developer: TDUnit

  1. Hallo,

    das TDUnit.zip File läßt sich nicht entpacken!? Ich würde es gerne einmal testen, ist es möglich diese auch per Mail zu bekommen?

    Beste Grüße
    Jörg Bertram

  2. Diana T. says:

    Hallo,
    wie kann ich diese TDUnit.app für Komponenten benutzen, die in einer ältere Version (TD 2.1) geschrieben sind nutzen?
    Grüße
    Diana

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: