© DrHitch/Shutterstock.com
jQuery Mobile

2 JavaScript Unit Test mit QUnit


Natürlich gibt es mittlerweile eine Vielzahl an JavaScript-Testframeworks. In den vergangenen Jahren haben sich hauptsächlich zwei Arten von Testframeworks herauskristallisiert.

Zum einen sind es Frameworks wie Jasmine und Mocha, die einen Behaviour-driven-Design-(BDD-)Ansatz verfolgen. Zum anderen sind es Frameworks, die den klassischen xUnit-Ansatz verfolgen und hier durch das Framework QUnit vertreten werden sollen.

Wer bereits in anderen Programmiersprachen mit Frameworks dieser Kategorie zu tun hatte, wie beispielsweise JUnit in Java, wird sich mit der Art der Tests schnell anfreunden.

2.1 Grundlagen QUnit

Im Folgenden werden anhand von Beispielen die einzelnen Bestandteile der Unit Tests mit QUnit beschrieben. Wie bereits in Kapitel 1 angesprochen, werden die Testdateien in einem Ordner mit Namen test abgelegt.

Um QUnit verwenden zu können, benötigen wir die JavaScript-Datei qunit-1.12.0.js, wobei 1.12.0 die Version ist und bei älteren bzw. neueren Versionen anders lautet. Des Weiteren benötigen wir noch die QUnit-CSS-Datei, die die gleiche Versionsnummer wie die JavaScript-Datei haben muss. In unserem Fall also qunit-1.12.0.css.

Obwohl jQuery für die Funktionalität von QUnit nicht benötigt wird, erleichtert es doch das Schreiben von Tests, weshalb ich es generell mit einbinde. Wie dies sich in einem HTML-Header auswirken könnte, zeigt Listing 2.1.

Um die Ausgaben der Unit Tests von QUnit in einer Webseite sichtbar zu machen, fehlen jetzt nur noch zwei DIV-Container mit den IDs qunit und qunit-fixture, die im body der Seite erstellt werden müssen.

<head>

<link href="../css/libs/qunit-1.12.0.css" rel="stylesheet"/>
<script src="../js/libs/jquery-1.10.2.js"></script>
<script src="../js/libs/qunit-1.12.0.js"></script>
<script src="../js/test/tests.js"></script>
</head>

Listing 2.1: Typischer Header einer Webseite mit QUnit Tests

Wenn man nun die fertige HTML-Datei ausführt, erhält man bereits eine QUnit-Ausgabe, die jener in Abbildung 2.1 ähnelt. Der Titel entspricht dem title im head-Bereich der HTML-Seite. Danach folgen noch die Checkboxen für Optionen, um erfolgreiche Tests auszublenden, globale Variablen zu erkennen oder try-catch auszuschalten.

Abb_2_1.png

Abbildung 2.1: Erste Ausgabe von QUnit ohne definierte Tests

Nach den Optionen findet sich die Browseridentifikation des verwendeten Browsers. Für Abbildung 2.1 wurde ein Chrome Browser auf einem 64-bit Windows 7 verwendet. Zu guter Letzt folgt die Zusammenfassung der durchlaufenen Tests. Da wir im Augenblick noch keine Tests geschrieben haben, wurden natürlich auch keine angezeigt, und auch die Zusammenfassung ist eher uninteressant.

Um einen ersten Test zu erstellen, folgen wir der Syntax test("kurze Beschreibung",Funktion), wobei die Funktion in der Regel, wie auch in Listing 2.2 zu sehen, als anonyme Inline Function implementiert wird.

test("leerer Test",function(){

});

Listing 2.2: Definition eines leeren QUnit Tests

QUnit erwartet mindestens eine Annahme (Assertion) in jedem Test, weshalb es jetzt auch, wie in Abbildung 2.2 zu sehen, eine aussagekräftige Fehlermeldung wirft, die genau dies aussagt.

Abb_2_2.png

Abbildung 2.2: Test fehlgeschlagen

Diesen Fehler kann man nun auf zweierlei Arten beheben: Entweder, wie in Abbildung 2.2 vorgeschlagen, durch Einfügen des Aufrufs expect(0) im Test oder durch Verwendung einer Dummy-Annahme, wie in Listing 2.3 zu sehen.

test("leererTest",function(){
ok(true,"Dummy-Assertion");
});

Listing 2.3: Leerer Test mit einer Dummy Assertion

Asserts in QUnit

In Listing 2.3 haben wir ja schon unsere erste Annahme verwendet. Es ist der einfachste der zur Verfügung stehenden Asserts, die ok-Annahme. Ihr erster Parameter ist ein boolescher Wert, der zweite Parameter wieder ein kurzer beschreibender String. Allerdings hat man hier nur implizit die Möglichkeit, den Erwartungswert anzugeben. Die Annahme schlägt fehl, sobald der erste Parameter den Wert false hat.

Der nächste Assert ist der equal-Assert. Seine Syntax bietet anders als die des ok-Asserts einen Parameter für den Erwartungswert. Seine Syntax, wie auch im Beispiel in Listing 2.4 zu sehen, ist: equal(wert, erwarteter_wert, "kurze Beschreibung").

test("Testing equalAssert", function() {
var zeichenkette = "222";
var zahl = 222;
equal(zeichenkette, zahl,
"Der Wert der Variablen zeichenkette ist
gleich dem Wert zahl");
});

Listing 2.4: Beispiel für das „equal“-Assert

Diese Annahme bildet den einfachen Vergleichsoperator (==) ab. Deshalb wird der Test aus dem Beispiel in Listing 2.4 erfolgreich durchlaufen.

Wer den Typ des Parameters mit überprüfen möchte, sollte den mächtigeren „Bruder“ des equal-Asserts, den strictEqual-Assert, verwenden. Wie der Name bereits vermuten lässt, verwendet diese Annahme den strikten Vergleichsoperator (===). Die Parameterliste ist analog zum equal-Assert. Wenn wir die Parameter aus Listing 2.4 verwenden würden, würde der Test fehlschlagen. Gibt man als Erwartungswert die Zahl 222 ein, wie in Listing 2.5 zu sehen, wird der Test erfolgreich durchlaufen.

test("Testing strictEqual Assert", function() {

strictEqual(zahl, 222, "Wert und Typ der beiden Objekte
ist gleich");
});

Listing 2.5: Beispiel eines „strictEqual“-Asserts

Sollte man ganze Objekte vergleichen wollen, hält QUnit das deepEqual-Assert bereit. Die Syntax ist übereinstimmend mit equal und strictEqual, nur dass die beiden Parameter für Wert und Vergleichswert jetzt Objekte sind. In Listing 2.6 wird ein einfaches Objekt mit zwei Attributen (age und name) verwendet, welches mit einer identischen Kopie über die deepEqual-Annahme verglichen wird. Es werden sowohl die Attributnamen als auch die Werte miteinander verglichen, wobei für die Werte der strikte Vergleichsoperator verwendet wird.

test("Testing deepEqual Assert", function() {
varsimple_object = {name: "Marco", age: 38};
varcopy_object = {name: "Marco", age: 38};
deepEqual(simple_object, copy_object,
"Die beiden Objekte und ihre inneren
Strukturen sind gleich");
});

Listing 2.6: Beispiel für „deepEqual“-Assert

Um auch für den Fall der erwünschten Nichtgleichheit den Komfort der Annahmen equal, strictEqual und deepEqual zu haben, stellt QUnit entsprechend notEqual, notStrictEqual und notDeepEqual zur Verfügung. Sie werden ebenfalls mit den Parametern Wert, Erwartungswert und Kurzbeschreibung aufgerufen, nur dass sie für den Gleichheitsfall den Test fehlschlagen und im Fall der Ungleichheit erfolgreich durchlaufen lassen.

test("Testing not* Asserts", function() {
varzeichenkette = "222";
varzahl = 222;
varsimple_object = {name: "Marco", age: 38};
varbad_copy_object = {name: "Hans", age: 28};
notEqual(zahl, "232",...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang