Dieser Abschnitt beschreibt die Funktionsweise von checkerberry db anhand der drei Test-Phasen die in Abschnitt 1.3.3.1, „Test-Ablauf“ beschrieben sind.
In den Code-Beispielen werden in der Regel die Spezifika der konkreten Testframeworks JUnit3, JUnit4 oder TestNG nicht aufgeführt, da sie in den meisten Fällen für das Verständnis des Beispiels nicht benötigt werden.
Checkerberry db wird eingesetzt, um Funktionen mit einer integrierten Datenbank zu testen. Generell benötigen Tests einen klar definierten Eingabezustand, um nach der Durchführung der zu testenden Komponente den erwarteten Ergebniszustand prüfen zu können. Im Fall von integrierten Datenbanktests bedeutet dies, dass der Inhalt der Datenbank vor dem Test in einen definierten Zustand versetzt werden muss. Zu diesem Zweck spielt checkerberry db in der Setup-Phase initiale Testdaten in die Datenbank ein.
Bevor initiale Testdaten in die Datenbank eingespielt werden
können, muss checkerberry db die einzuspielenden Testdaten ermitteln.
Die Definition der Testdaten erfolgt über XML-Dateien. Der Name der
Datei ergibt sich implizit aus dem Namen der Testklasse und dem Namen
der Testmethode: <Name der Testklasse>_<Name der
Testmethode>_initial.xml
z.B.
UserDaoTest_testInsertUser_initial.xml
. Die
Ermittlung der Namen der Testdaten ist konfigurierbar (siehe Abschnitt 2.4.18, „Namenskonvention der XML-Testdaten anpassen“).
Die Testdaten werden im Klassenpfad, an der gleichen Stelle wie die zugehörige Testklasse gesucht.
Beispiel 2.1. Beispiel UserDaoTest.testInsertUser
package de.conceptpeople.sample.dao; public class UserDaoTest extends AbstractSampleTestCase { /** * Testet das Anlegen eines neuen Users. * @throws Exception wenn der Test fehlschlug. */ public void testInsertUser() throws Exception { // Neues User-Objekt erzeugen… User user = new User("Homer", "Simpson", "16.09.1946"); // …und in der Datenbank speichern. boolean success = dao.save(user); // Prüfen über JUnit-Methode, ob das Speichern erfolgreich war. assertTrue(success); // Testhandler aus der Umgebung holen. DbTestHandler testHandler = getEnvironment().getTestHandler(); // Die initialen Daten dürfen sich nicht geändert haben. testHandler.assertInitialDataUnchanged(); // Der Datenbankinhalt muss die erwarteten Daten beinhalten. testHandler.assertEqualsExpected(); }
In obigen Code-Beispiel ist die Testklasse
UserDaoTest
dargestellt. Bei der Durchführung der
Setup-Phase für die Testmethode testInsertUser
werden die initialen Testdaten aufgrund von Klassen- und Methodenname in
der Datei UserDaoTest_testInsertUser_initial.xml
gesucht.
Aufgrund der Package-Spezifikation
de.conceptpeople.sample.dao
wird die Klasse für
UserDaoTest
bei der Kompilierung in dem
Unterverzeichnis de/conceptpeople/sample/dao
des
Klassenpfads erstellt. In diesem Unterverzeichnis werden auch die
Testdaten gesucht. In dem aktuellen Beispiel sind die Testdaten in der
Datei UserDaoTest_testInsertUser_initial.xml
definiert.
Beispiel 2.2. Beispiel UserDaoTest_testInsertUser_initial.xml
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE dataset PUBLIC "-//ConceptPeople//DTD sample-db 1.0//EN" "../sample-db.dtd"> <dataset> <USERS NAME="Bart" SURNAME="Simpson" BIRTHDATE="2009-03-18"/> <USERS NAME="Lisa" SURNAME="Simpson" BIRTHDATE="2009-03-18"/> <USERS NAME="Maggie" SURNAME="Simpson" BIRTHDATE="2009-03-18"/> <USERS NAME="Marge" SURNAME="Simpson" BIRTHDATE="2009-03-18"/> </dataset>
Das oben angegebene Beispiel enthält eine Testdatendatei. Die
Testdaten werden unter dem Tag dataset
definiert.
Innerhalb dieses Tags werden die einzuspielenden Datensätze angegeben.
In dem obigen Beispiel werden vier Datensätze in die Datenbanktabelle
USERS
eingespielt. Zu diesem Zweck sind in den
Testdaten vier USERS
-Tags definiert, die die
Werte der Spalten NAME
,
SURNAME
und BIRTHDATE
enthalten.
In vielen Situationen verwenden unterschiedliche Testmethoden
einer Testklasse die gleichen initialen Testdaten. In diesen Situationen
ist es sinnvoll, die Testdaten nicht auf Methoden-, sondern auf
Klassenebene zu definieren. Für das obige Beispiel können die Testdaten
somit ebenfalls in der Datei
UserDaoTest_initial.xml
gespeichert werden. Die
Suche der initialen Testdaten erfolgt in checkerberry db in zwei
Schritten: Zunächst werden die Testdaten auf Methodenebene unter dem
Namen UserDaoTest_testInsertUser_initial.xml
gesucht. Wenn diese Datei nicht vorhanden ist, werden die Testdaten auf
Klassenebene unter dem Namen
UserDaoTest_initial.xml
gesucht.
Dieses Konzept minimiert den Verwaltungsaufwand und wird unter dem Namen „Convention over Configuration“ in vielen Frameworks angewendet. Im konkreten Fall von checkerberry db ist nahezu kein Verwaltungsaufwand für das Einspielen der Testdaten erforderlich. Natürlich muss der Software-Entwickler die initialen Testdaten definieren. Diese Aufgabe ist jedoch in jedem Fall erforderlich. Das Testframework kann lediglich dafür Sorge tragen, dass das Einbinden der Testdaten keinen großen Aufwand erzeugt.
Wenn checkerberry db initiale Testdaten findet, wird zunächst der Inhalt aller Tabellen in der Datenbank gelöscht. Danach werden die gefundenen Testdaten in die Datenbank eingespielt. Wenn keine Testdaten gefunden werden, bleibt der Inhalt der Datenbank unverändert.
Das checkerberry test center stellt einen Caching-Mechanismus zur Verfügung, der das überflüssige Löschen und Einspielen von Tabellen verhindert. Die Funktionsweise des Caches ist in Abschnitt 2.4.14, „Performance-Optimierung durch Caching von Tabellen“ beschrieben. Darüber hinaus besteht auch die Möglichkeit, Tabellen vollständig aus der Verwendung von checkerberry db auszuschließen. Dies kann z.B. bei temporären Tabellen sinnvoll sein. Dieses Feature ist unter Abschnitt 2.4.6, „Ignorieren von Datenbanktabellen“ beschrieben.
Checkerberry db bietet einige Features, um das Löschen der gesamten Datenbanktabellen in der Setup-Phase zu umgehen (siehe Abschnitt 2.4.16, „Einspielen von Testdaten temporär unterdrücken“).