Writing Effective JavaScript Unit Tests mit YUI Test
5. Januar um 10.38 Uhr 2009 von Nicholas C. In Zakas | Entwicklung | 4 KommentareEiner der größten Unter-der-Radar-Bewegungen in der JavaScript-Entwicklung im Jahr 2008 war das Wiederaufleben des Interesses für Unit-Tests. YUI Test , YUI's Unit Testing Framework, erreichte GA-Status im Februar und anderen Bibliotheken entweder eingeführt eigene Unit Testing Frameworks oder begonnen Bekanntmachung bestehenden. Als Ergebnis gibt es noch viel mehr Unterlagen über die Erstellung von Unit-Tests für JavaScript. Simply mit JavaScript Unit-Tests ist nicht genug, obwohl, wenn Sie Ihre Tests falsch geschrieben sind, können sie eine Menge Zeit verloren führen. Lernen effektiver zu schreiben JavaScript Unit-Tests sparen Sie Zeit und Nerven in die Zukunft.
Was machst du testen?
Der Schlüssel zum Schreiben effektiver Unit-Tests ist es, das Wort zu verstehen "Einheit." In Tests gesehen ist eine Einheit einem isolierten Teil des Codes, der unabhängig von den anderen getesteten Teile des Codes werden können. In einer objektorientierten Sprache wie JavaScript, ist jede Methode als eine Einheit werden. Proper OO-Design bringt in der Regel gut gekapselt Methoden, die einem einzigen Zweck dienen und sind daher einfach zu testen.
Traditionelle Unit-Tests soll die Implementierung einer Schnittstelle zu testen, also private Methoden nicht explizit testen zu lassen. Dies wird als "Black Box Tests. Die Idee ist, dass man die Swap-Implementierung einer Schnittstelle und der Unit-Tests wird alles noch passieren, weil sie völlig agnostisch auf die zugrunde liegende Implementierung sind. Alle Tests wissen, ist eine Reihe von Auflagen, die erfüllt sein müssen, sie nicht, wie diese Grenzen eingehalten werden.
Writing Tests
Wie ich in meiner Rede gesagt, sollte Unit-Tests testen Ein-und Ausgänge. Die Eingänge können benannte Methode Argumente oder Veränderungen in global zugängliche Variablen werden, dass die Methode abhängt, um richtig zu funktionieren. Ausgänge können Werte zurückgeben werden, Veränderungen im Zustand der Variablen und sogar Fehler geworfen. Für jeden Input-Output eingestellt haben, sollte eine Einheit zu testen. Jede Prüfung sollte ausdrücklich festgestellt, "da diese Eingänge erwarte ich, dass diese Ausgänge." Jede Abweichung von dieser Aussage ist ein Test fehlgeschlagen.
Jede Prüfung sollte so einfach wie möglich und nur ein Test Input-Output-gesetzt; Sets kombinieren in einem einzigen Test minimiert die Wirksamkeit des Gerätes zu testen. Betrachten wir zum Beispiel den folgenden Test einer Funktion namens trim() :
var = new TestCase YAHOO.tool.TestCase (( Name: "trim () Tests", testTrim: function () ( var Ergebnis1 = trim ("Hallo Welt"); YAHOO.util.Assert.areEqual ("Hallo Welt", Ergebnis1 "Führende Leerzeichen sollte entfernt werden."); var result2 = trim ("Hallo Welt"); YAHOO.util.Assert.areEqual ("Hallo Welt", result2, "Trailing Leerraum sollte beraubt werden."); ) ));
Hier die testTrim() der Testfall ist die Methode tatsächlich zwei verschiedene Tests Input-Output-Sets:
- Input string verfügt über führende Leerzeichen; Rückgabewert hat keine führenden Leerzeichen.
- Input string hat anhängenden Leerzeichen; Rückgabewert hat keine anhängenden Leerzeichen.
Das Problem ist, dass diese beiden Sätze buchstäblich keine Beziehung zueinander haben, aber wenn der erste Input-Output-Set nicht das richtige Ergebnis zu produzieren, wird der zweite Satz noch nie getestet werden. Dies ist eine Situation, wo eine Störung Masken anderen. Es ist effektiver zu trennen diesen Input-Output-Sets in zwei Prüfungen:
var = new TestCase YAHOO.tool.TestCase (( Name: "trim () Tests", testTrimWithLeadingWhiteSpace: function () ( var result = trim ("Hallo Welt"); YAHOO.util.Assert.areEqual ("Hallo Welt", result, "Führende Leerzeichen sollte entfernt werden."); ) testTrimWithTrailingWhiteSpace: function () ( var result = trim ("Hallo Welt"); YAHOO.util.Assert.areEqual ("Hallo Welt", result, "Trailing Leerraum sollte beraubt werden."); ) ));
Dieser Code testet das jetzt richtig trim() -Funktion der Input-Output-Sets, sie getrennt zu halten.
Unit Tests sind immer so, wenn der Code getestet funktioniert korrekt geschrieben. Gute Software-Design beinhaltet Kartierung dieser Input-Output-Sets vor der Zeit, so dass Sie genau wissen, was das Ergebnis sollte in jedem Fall sein. Auf diese Weise werden Unit-Tests eine Art technische Anforderung Dokument zusätzlich zur eigentlichen Code.
Effektive Behauptungen
Einer der wichtigsten Teile des Schreibens Unit-Tests ist richtige Behauptung Definition. Jede Behauptung gibt eine Bedingung, die, wenn nicht erfüllt, zeigt, dass die Funktionalität nicht angemessen verhalten. Es ist wichtig, nur so viele Behauptungen wie nötig, um richtig zu testen den Code ausgegeben. Zu viele falsche Behauptungen Ausfällen führen, während zu wenig können zu falschen Pässe führen.
Im vorherigen Beispiel enthält jeder Test eine einzige Behauptung, dass, weil alles, was benötigt wird. Ich weiß genau der Wert, der zurückgegeben werden und so habe ich eigens für diesen Test. Die Prüfungen können sowohl sehr einfach aussehen, aber sie bekommen den Job zu erledigen. Auch hier gibt's keine Regel über die Anzahl von Behauptungen, dass ein guter Test zu machen, so stellen Sie sicher, Sie testen jeden erwartete Ausgabe des Codes für den Eingang gegeben.
Um Ausfälle Test kohärenter, sollten Sie eine Fehlermeldung mit jeder Behauptung. In YUI Test ist dies immer das letzte Argument der Methode jede Behauptung. Eine Fehlermeldung sollte Ihnen sagen, was sollte geschehen, was nicht geschah. Einige Beispiele:
/ / Bad Fehlermeldung YAHOO.util.Assert.areEqual ("Hallo Welt", Ergebnis: "Das Ergebnis war nicht 'Hallo Welt'"); / / Gut Fehlermeldung YAHOO.util.Assert.areEqual ("Hallo Welt", result, "Führende Leerzeichen sollte entfernt werden.");
Beachten Sie den Unterschied zwischen schlechter und guter Fehlermeldungen: die schlechte erfahren Sie, was passiert und das gute sagt Ihnen, was zu erwarten war. Bei der Ausführung Ihrer Tests, ein Versagen zeigt bereits, dass etwas passiert unerwartete, es gibt also keine Notwendigkeit, wiederholen Sie einfach, dass etwas passiert unerwarteter. Es ist eher hilfreich zu wissen, was hätte geschehen sollen, weil sie eine genaue Darstellung Ihrer Anforderung ist. Mit diesem Ansatz, wobei bis Ende Ausfälle eine Liste von nicht erfüllten Anforderungen, dass Sie zurückkommen und auswerten können.
Arbeiten mit dem DOM
JavaScript ist einzigartig in andere Sprachen, da sie häufig in Verbindung steht mit der Umwelt, der DOM. Methoden, die stark die Interaktion mit der DOM sind schwer zu Unit-Test, da die gesamte Umgebung eingerichtet werden müssen, damit die Methode vollständig auszuführen. Sache noch weiter verkompliziert wird die Tendenz von JavaScript durch eine Aktion des Anwenders wie ein Mausklick ausgelöst werden. YUI Test bietet Ereignis-Simulation zu schaffen Tests für Methoden, die abhängig DOM Interaktion sind Beihilfen jedoch, diese zu überqueren beginnt in den Bereich des Funktionstests.
Funktionale Tests, wie zum Unit-Tests im Gegensatz soll die Benutzer-Erfahrung mit dem Produkt statt Input-Output-Sets für Code zu testen. Wenn Sie meinen zu testen, dass die Benutzeroberfläche in einer bestimmten Weise durch die Interaktion der Nutzer reagiert, dann haben Sie wirklich wollen einige funktionelle Tests schreiben, anstatt Unit-Tests. YUI Test Tests können verwendet werden funktionelle schreiben einige grundlegende, aber die beliebteste (und ziemlich gut)-Tool für solche Tests ist Selen .
Der beste Weg, um festzustellen, ob etwas ist ein Unit-Test ist zu fragen, ob es vor dem Code, dass es zur Prüfung der schriftlichen kann tatsächlich existiert. Unit-Tests, als Teil des Test-Driven Development, sind eigentlich soll im Vorfeld der eigentlichen Code als einen Weg zur Entwicklungsanstrengungen Guide geschrieben werden. Funktionale Tests, auf der anderen Seite kann nicht vor der Zeit existieren, weil sie so um die Benutzeroberfläche gebunden und wie sie Veränderungen als Reaktion auf die Interaktion der Nutzer sind.
Strukturierung Testhierarchien
YUI Test, genau wie andere Unit Testing Frameworks unterstützt eine Hierarchie von Testfällen und Suiten. Jeder Test-Suite können andere Test-Suiten sowie Testfälle; nur Testfälle können eigentlichen Tests (Methoden, beginnend mit dem Wort "test" enthalten). Der beste Weg, um Ihren Test-Hierarchie zu organisieren, ist zu einer sehr einfachen Muster folgen:
- Erstellen Sie eine Test-Suite für jedes Objekt zu testen, wirst du bist.
- Erstellen Sie ein Testfall für jede Methode eines Objekts du bist zu testen, und fügen Sie ihn auf das Objekt der Test-Suite.
- Erstellen Sie einen Test in jedem Testfall für jeden Input-Output-gesetzt.
Auf diese Weise Ihren Testhierarchie Spiegeln Sie den Code Sie testen und es ist leichter, herauszufinden, wo neue Tests erstellt werden soll.
Führen Sie Ihre Tests!
Vielleicht der wichtigste Teil der Unit-Tests ist es, Ihre Tests häufig ausgeführt werden. Testen ist nur wirksam, wenn auf einer regelmäßigen Basis. Zumindest sollten Sie in Ihrem Betrieb Unit-Tests vor der Kontrolle in Veränderungen der Quellcodeverwaltung. Optimal, dann würden Sie auch die Tests automatisch in regelmäßigen Abständen auf etwaige Änderungen, nachdem sie der Quellcodeverwaltung begangen habe validieren. Dies ist, wie Sie den größten Vorteil des Unit-Test: schnell Einsicht zu erhalten, und hoffentlich Prävention, der Regressionen.
Weitere Informationen
- YUI Test
- YUI Theater: Test Driven Development mit YUI Test von Nicholas C. Zakas
- FireUnit
- FireUnit Erweiterung für YUI Test
- JavaScript ist Too Code: Test It!
- JavaScript Unit Test Isolation
Sagen und erweitern: Lesezeichen mit del.icio.us | Digg it! | reddit!
4 Kommentare »
RSS-Feed für Kommentare zu diesem Beitrag.
Hinterlasse einen Kommentar

Copyright © 2006-2010 Yahoo! Inc. Alle Rechte vorbehalten. Datenschutzbestimmungen - Nutzungsbedingungen
Powered by WordPress auf Yahoo! Web Hosting .

Sind die YUI-Tests laufen automatisch auf regelmäßiger Basis? Wenn ja kann Ihnen teilen keine Informationen darüber, wie Sie dies tun? Ich bin besonders interessiert, wie Sie mit Laich-und Schließen des Browser-Deal-Prozesse verwendet, um die Tests in während eines automatisierten Build laufen, und auch wie Sie und sammeln Sie aggregieren die Testergebnisse für den Build.
Kommentar von Simon - 5. Januar 2009 #
Die beste Lösung, die ich gesehen habe thusfar ist die Verwendung von Selen, um den Browser zum Testen Lebenszyklus zu verwalten. Sie können es bis zu laufen und dann in regelmäßigen Abständen überwacht die Seite für die Ergebnisse.
Kommentar von Nicholas C. Zakas - 7. Januar 2009 #
Zunächst einmal danke für das Schreiben dieses wunderbaren Blog-Eintrag. Ich möchte auf den folgenden Kommentar:
Persönlich bevorzuge einer Klasse als Einheit zu denken. Die Klasse stellt mir einige Verhaltensweisen, und ich möchte, dass mein Verhalten durch Tests zu erklären. Going am Ebene eine Methode scheint, dass wir in der Umsetzung in gewissem Sinne Bohren.
Ich würde es vorziehen, wenn Sie den Stil der Unit-Tests als staatliche basierte Unit-Tests qualifiziert. Es ist eine andere Schule der Unit-Tests, die in Wechselwirkung glaubt Testen. Wenn ihr nicht so viel über die Produktion im Hinblick auf Werte zurückgeben, Änderungen im Zustand von Variablen oder Fehler geworfen. Der Schwerpunkt liegt auf der Interaktion (Methode nennt) mit seinen Mitarbeitern.
Sie scheinen zu Defekten der xUnit Konvention haben. in xUnit Fehlermeldung ist immer das erste Argument.
Sie behauptet:
Während ich stimme mit Ihnen überein, dass das zweite Beispiel besser als der erste ist, aber ich denke die Fehlermeldung im zweiten Fall ist überflüssig. Wenn man sich das ganze Prüfverfahren unten
testTrimWithLeadingWhiteSpace: function(){var result = trim(" Hello world");
YAHOO.util.Assert.areEqual("Hello world", result, "Leading white space should be stripped.");
}
Die Methode Name schon sagt Ihnen, dass führende Leerraum getrimmt werden soll oder gezupft. In diesem speziellen Fall würde ich keinerlei Fehlermeldung. Wenn Ihr Unternehmen seinen besten Praxis wird man geben, dann würde ich lieber Ihr Versäumnis Nachricht als "Leading Leerraum war nicht entkleidet"
Dies ist nicht immer wahr. In vielen Fällen kann man eigentlich schreiben Sie Funktions-oder Abnahmetests, bevor Sie Code erstellen. Wenden Sie sich an Acceptance Test Driven Development
Warum ist das wichtig? Ich sehe nicht, wie dies helfen wird?
Ich würde eher ein Test-Klasse pro wichtige Stelle in meiner Produktion Code und schreibe eine Testmethode pro Verhalten der Klasse erfüllt. Manchmal könnte ich mehr als 1-Test für eine Methode und manchmal keines haben. Ich bin mir nicht sicher, ob ich eine Leitlinie sagen jede Methode sollte ein Test hätte schaffen.
Kommentar von Naresh Jain - 11. Januar 2009 #
Hallo Naresh,
Vielen Dank für Ihre hilfreichen Kommentare. Tatsächlich gibt es viele Schulen der umliegenden Testmethodik Gedanken, und du hast auf ein paar von ihnen berührt. Ich möchte nur ein paar Punkte zu klären.
Making the Assertionsfehler Meldung eine Erklärung dessen, was geschieht, sollte nicht redundant, es erläuternd, was gerade passiert. Der Test-Namen und die Fehlermeldung ähnlich sein, und in diesem Fall, weil der Test ist so einfach, aber sie können sehr unterschiedlich sein, wenn es eine Reihe von Behauptungen im Test enthalten sind.
Meine Empfehlung zur Einrichtung Testsuiten und Testfälle ist, Menschen begonnen. Ich sage nicht, dass jede Methode sollte ein Test sein, ich sage, dass jede Methode sollte ein Testfall mit Tests, erkunden jeden Input-Output-Set, das Sie haben. Der Punkt ist, dass eine logische Struktur haben, dass die Karten direkt an den Objekten, die Sie programmieren.
Ich hoffe, dies klärt einige der Punkte, vielen Dank für Ihre Kommentare.
Kommentar von Nicholas C. Zakas - 12. Januar 2009 #