Testen

Zum von einer Qt-Anwendung oder Qt-Bibliothek steht QTestLib zur Verfügung. Dieses Framework bietet alles, was für Unit Tests notwendig ist. Die wichtigsten Makros für Testmethoden (siehe auch QTest) sind:

QCOMPARE(actual, expected)
QVERIFY(condition)
QVERIFY2(condition, message)
QFAIL(message)

Überlicherweise enthält ein Testprojekt genau eine Testklasse, d. h. dass man normalerweise mehrere Testprojekte und damit Binaries zu Testen pro Projekt anlegt. Um nun alle Tests gleichzeitig ausführen zu können, braucht man eine Test Suite. Eine Test Suite für ein Projekt lässt sich ganz leicht anlegen, in dem in jedem Testprojekt das Project File CONFIG += testcase ergänzt wird. Nun kann man in einem übergeordneten Verzeichnis, in dem alle Testprojekte liegen die alle Test mit qmake check ausführen. Details dazu finden sich offizielle Qt-Wiki.

Äußerst hilfreich beim Testen ist es zu wissen, welcher Code beim Test durchlaufen wird. Vor allen lassen sich so Lücken im Test entdecken. Aber auch nicht benötigtiger Code lässt sich so entdecken, wenn man nach dem Test-First-Ansatz (auch Test Driven Development genannt)  programmiert.

Mit gcov lässt sich die Code Coverage bestimmen. Dazu muss im *.pro-File der Tests bzw. des zu testenden Projekts die folgenden Einstellungen gemacht werden.

QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage
LIBS += -L/Developer/usr/lib -lprofile_rt

Die zweite Zeile LIBs muss für andere Plattformen als Mac OS X abgepasst werden. Beim Kompilieren wird der Code instrumentiert und um zusätzliche Anweisung ergänzt, um die Code Coverage zu bestimmen. Dabei werden zusätzliche Files mit der Endung *.gcda bzw. *.gcno angelegt. Nun muss der Test ausgeführt werden.

Im Anschluss lässt sich mit gcov {source-file} die Code Coverage bestimmen. Der Aufruf gibt nur eine Prozentzahl aus, erstellt aber eine weitere Datei *.{source-file}.gcov. In dieser stehen die Details. Optisch ansprechender als ein reines Textfile ist natürlich ein HTML-Report. Ein solcher lässt sich ansprechend mit lcov erstellen.

Zur Integration in ein Continous Integration wie Jenkins (bzw. Hudson) gibt das Python-Skript gcovr. Dieses wandelt die Ausgabe von gcov um in ein XML-Format, welches von dem Cobertura-Plugin für Jenkins gelesen werden kann. Der Aufruf von gcovr lautet z. B.

gcovr --root=${WORKSPACE} --exclude=moc_* --xml >${WORKSPACE}/test/test-coverage.xml

Das Skript muss für den Aufruf im Path stehen. Im Beispiel habe ich die Metadateien von qmake bei der Code Coverage ausgenommen: moc_*

Zurück