Tests atomar halten
Problem
Wenn Tests zusammen gebaut werden, kann es passieren, dass manche erfolgreich sein sollten, aber als fehlerhaft bewertet werden und umgekehrt. Dies ist das Ergebnis eines Tests, der aufgrund eines Seiteneffekts eines vorigen Tests falsche Ergebnisse liefert:
test("2 Asserts", function() { $("#main").append("<div>Hier klicken für <span class='bold'>Nachrichten</span>.</div>"); deepEqual($("#main div").length, 1, "Nachrichten-Link hinzugefügt"); $("#main").append("<span>Sie haben eine Nachricht!</span>"); deepEqual($("#main span").length, 1, "Benachrichtigung hinzugefügt"); });
Beachten Sie, dass das erste append()
einen <span>
hinzufügt, den die zweite Assertion
nicht berücksichtigt.
Lösung
Nutzen Sie die Methode test()
, um die Tests atomar zu halten und achten
Sie darauf, dass jede Assertion frei von möglichen Seiteneffekten
ist. Sie sollten sich nur auf das feste Markup innerhalb des
#main
-Elements verlassen. Ein
Verändern und Aufbauen auf irgendetwas anderem kann zu
unerwünschten Effekten führen:
test("Test 1", function() { $("#main").append("<div>Hier klicken für <span class='bold'>Nachrichten </span>.</div>"); deepEqual($("#main div").length, 1, "Nachrichten-Link hinzugefügt"); }); test("Test 2", function() { $("#main").append("<span>Sie haben eine Nachricht!</span>"); deepEqual($("#main span").length, 1, "Benachrichtigung hinzugefügt"); });
QUnit setzt die Elemente innerhalb des
#main
-Elements nach jeden Test zurück
und entfernt alle Events, die eventuell vorhanden waren. Solange
Sie Elemente nur innerhalb dieses festen Rahmens nutzen, müssen Sie
nach Ihren Tests nicht selbst aufräumen, um sie atomar zu
halten.
Diskussion
Neben dem festen Element #main
räumt QUnit auch die Eigenschaften von
jQuery selbst auf: $.event.global
und
$.ajaxSettings
. Alle globalen Events
wie $().ajaxStart()
werden von jQuery
in $.event.global
verwaltet – hat Ihr
Test viele davon gebunden, kann der Test Runner dadurch deutlich
langsamer werden, wenn er viele Tests ausführen muss. Durch das
Aufräumen dieser Eigenschaft stellt QUnit sicher, dass Ihre Tests
nicht von globalen Events beeinflusst werden.
Das gleiche gilt für $.ajaxSettings
, das im Allgemeinen über
$.ajaxSetup()
genutzt wird, um die
allgemeinen Eigenschaften für Aufrufe von $.ajax()
zu definieren.
Neben den in Durchzuführende Tests auswählen beschriebenen Filtern
stellt QUnit auch noch den Schalter ?noglobals
bereit. Schauen Sie sich den folgenden
Test an:
test("globale Verschmutzung", function(){ window.pollute = true; deepEqual(pollute, true); });
In einem normalen Testlauf führt das zu einem
erfolgreichen Test. Führt man den gleichen Test mit dem noglobals
-Schalter durch, schlägt der Test
fehl, weil QUnit erkennt, dass das Window-Objekt »verschmutzt«
wurde.
Es ist nicht notwendig, diesen Schalter immer zu verwenden, aber er kann sehr nützlich sein, um das Verschmutzen globaler Namensräume zu erkennen, das in Kombination mit Fremd-Bibliotheken eventuell problematisch ist. Und er hilft dabei, Fehler in Tests zu erkennen, die durch Seiteneffekte ausgelöst wurden.