Open Source im professionellen Einsatz

Teil des Projekts

So vorbereitet setzen Entwickler konkrete Tests um. Damit sie die Übersichtlichkeit des Quellcode wahren, speichern sie die nötigen Dateien für die Tests in einen Unterordner »tests« ihres Projekts. Der Befehl »add_subdirectory(tests)« in der »CmakeLists.txt« des Projekts bindet den Unterordner ein. Die Testklasse für den ersten Test hat den Namen »TestMemoryMapmodel« und den bereits bekannten Header aus Listing1.

In der Implementierung sorgen der Befehl »#include testmemorymapmodel.moc« und die »qt4_automoc« -Funktion von Cmake dafür, dass der MOC-Compiler von Qt die Klasse bearbeitet und ihre Signale und Slots umwandelt. Die Prüfanweisungen für den Test befinden sich in der Funktion »addressRange()« (siehe Listing2). Für die Ausführung der Anweisungen müssen natürlich die Modellklasse und die Klasse »QTest« ebenfalls eingebunden sein.

Zunächst erzeugt der Test eine Instanz des Modells und ermittelt mit dem Code ab Zeile2 die Indizes für die zu prüfenden Objekte. Anhand ihres Namens aus der ersten Spalte des Modells prüft er ab Zeile 8, ob sie an der richtigen Stelle im Modellbaum stehen. Ist bis dahin kein Test fehlgeschlagen, prüft in den Zeilen 12 und 13 der Test die berechnete Speichergröße in der dritten Spalte des Modells. Das an die Konstante angehängte »ll« in der letzten Zeile teilt dem Compiler dabei mit, dass die Konstante, genau wie die Rückgabe des Modells, vom Typ »long long« ist. Ohne diese Angabe würde der Compiler Zahlenkonstanten als einfache Integers interpretieren und keine passende »QCOMPARE« -Variante finden.

Listing 2

Implementierung der ersten Testklasse

01 MemoryMapModel *model = new MemoryMapModel(domDocument, this);
02 QModelIndex area = model->index(0, 0);
03 QModelIndex sram = model->index(0, 2, area);
04 QModelIndex flash = model->index(1, 0, area);
05 QVERIFY(area.isValid());
06 QVERIFY(sram.isValid());
07 QVERIFY(flash.isValid());
08 QCOMPARE(model->data(model->index(area.row(), 0)).toString(), QString("area"));
09 QCOMPARE(model->data(model->index(sram.row(), 0, area)).toString(), QString("SRAM"));
10 QCOMPARE(model->data(flash, 0).toString(), QString("FLASH"));
11 QEXPECT_FAIL("", "Don't know how to handle untyped areas", Continue);
12 QCOMPARE(model->data(sram), QVariant());
13 QCOMPARE(model->data(model->index(flash.row(), 2, area)).toLongLong(), 1879048192ll);

Anwendungen mit Prüfausrüstung ausstatten

Die Anweisung in Zeile11 dient schließlich der Negation des Tests in Zeile 12. Dieser schlägt fehl, weil das Modell den Typ des Elements noch nicht berücksichtigt und daher eine Speichergröße bestimmt. Im fertigen Produkt sollte dies aber nicht mehr der Fall sein. Ihren Code schließen Entwickler mit dem Makro »QTEST_MAIN(TestMemoryMapModel)« ab, um Qt mitzuteilen, dass er eine Testklasse darstellt.

Die Zeilen in Listing3 aus der »CMakeLists.txt« im Verzeichnis »tests« binden den Test in das vorhandene Projekt ein. Daraufhin übersetzt ein »make« im Buildverzeichnis nach der Konfiguration durch »cmake ../« die Testanwendung. Nach dem Start mit »bin/testmemorymapmodel« sollte sie eine Ausgabe wie in Abbildung2 erzeugen. Darin ist der erwartete Fehlschlag zu erkennen, dass also die Testfunktion korrekt durchläuft. Wer nun »initTestCase()« und »cleanupTestCase()« hinzuzählt, erkennt die drei als bestanden gemeldeten Tests.

Nach diesem komplizierten ersten Test soll eine zweite Prüfung die Funktionstüchtigkeit des Modells sichern. Dazu bietet Nokia die Klasse »ModelTest« an, die nach häufigen Fehlern in Implementierungen des »QAbstractItemModel« -API Ausschau hält [5]. Um es zu nutzen, kopiert der Entwickler die Dateien »modeltest.h« und »modeltest.cpp« in das Verzeichnis »tests« . Die Testausführung findet in der hinzugefügten Funktion »void baseModelTest()« der Testklasse statt. In der Implementierung beginnt der Test mit:

MemoryMapModel *model = new MemoryMapModel(QDomDocument(), this);
ModelTest *modelTest = new ModelTest(model, this);

Der Code erzeugt eine Instanz des Modells und übergibt den Zeiger auf das Objekt an eine Instanz des Modeltests. Damit ist er an das »MemoryMapModel« angedockt und führt bei jeder Änderung des Modells einige Tests aus. Daher ist es nur noch nötig, einen Testdatensatz zu laden. Wenn der Entwickler »modeltest.cpp« zur Quellenliste hinzufügt und erneut »make« und »bin/testmemorymapmodel« ausführt, zeigt die Ausgabe der Testanwendung nunmehr vier bestandene Tests an.

Listing 3

Tests in das Cmake-Projekt einbinden

01 SET(QT_USE_QTTEST TRUE)
02 INCLUDE(${QT_USE_FILE})
03 INCLUDE_DIRECTORIES(
04   ${QT_INCLUDES}
05   ${CMAKE_CURRENT_BINARY_DIR}
06   ${CMAKE_CURRENT_BINARY_DIR}/../
07   ${CMAKE_CURRENT_SOURCE_DIR}/../
08 )
09 ADD_DEFINITIONS(${QT_DEFINITIONS})
10 SET(test_CPP
11   testmemorymapmodel.cpp
12   ../memorymapmodel.cpp
13   ../domitem.cpp
14 )
15 QT4_AUTOMOC(${test_CPP})
16 ADD_EXECUTABLE(testmemorymodel ${test_CPP})
17 TARGET_LINK_LIBRARIES(testmemorymodel${QT_LIBRARIES})

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 6 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Als digitales Abo

Als PDF im Abo bestellen

comments powered by Disqus

Ausgabe 07/2013

Preis € 6,40

Insecurity Bulletin

Insecurity Bulletin

Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...

Linux-Magazin auf Facebook