Lassen Sie mich zunächst Quellen einstecken - Pragmatic Unit Testing in Java mit JUnit (Es gibt auch eine Version mit C # -Nunit. Aber ich habe diese. Sie ist größtenteils agnostisch. Empfohlen.)
Gute Tests sollten eine REISE sein (Das Akronym ist nicht klebrig genug - ich habe einen Ausdruck des Spickzettel in dem Buch, den ich herausziehen musste, um sicherzustellen, dass ich das richtig verstanden habe.)
- Automatisch : Das Aufrufen von Tests sowie das Überprüfen der Ergebnisse auf PASS / FAIL sollte automatisch erfolgen
- Gründlich : Abdeckung; Obwohl sich Fehler in der Regel um bestimmte Regionen im Code gruppieren, stellen Sie sicher, dass Sie alle wichtigen Pfade und Szenarien testen. Verwenden Sie Tools, wenn Sie nicht getestete Regionen kennen müssen
- Wiederholbar : Tests sollten jedes Mal die gleichen Ergebnisse liefern. Tests sollten nicht auf unkontrollierbaren Parametern beruhen.
- Unabhängig : Sehr wichtig.
- Tests sollten jeweils nur eine Sache testen . Mehrere Behauptungen sind in Ordnung, solange sie alle eine Funktion / ein Verhalten testen. Wenn ein Test fehlschlägt, sollte er den Ort des Problems genau bestimmen.
- Tests sollten nicht aufeinander angewiesen sein - isoliert. Keine Annahmen über die Reihenfolge der Testausführung. Stellen Sie vor jedem Test sicher, dass der Schiefer sauber ist, indem Sie Setup / Teardown entsprechend verwenden
Professionell : Auf lange Sicht haben Sie so viel Testcode wie die Produktion (wenn nicht mehr). Befolgen Sie daher für Ihren Testcode den gleichen Standard für gutes Design. Gut faktorisierte Methodenklassen mit absichtsstarken Namen, keine Vervielfältigung, Tests mit guten Namen usw.
Gute Tests laufen auch schnell . Jeder Test, dessen Ausführung mehr als eine halbe Sekunde dauert, muss bearbeitet werden. Je länger die Testsuite für einen Lauf dauert, desto seltener wird sie ausgeführt. Je mehr Änderungen der Entwickler versucht, sich zwischen den Läufen zu schleichen. Wenn etwas kaputt geht, dauert es länger, um herauszufinden, welche Änderung der Schuldige war.
Update 2010-08:
- Lesbar : Dies kann als Teil von Professional betrachtet werden - es kann jedoch nicht genug betont werden. Ein Härtetest wäre, jemanden zu finden, der nicht zu Ihrem Team gehört, und ihn / sie zu bitten, das zu testende Verhalten innerhalb weniger Minuten herauszufinden. Tests müssen genau wie Produktionscode gepflegt werden - machen Sie das Lesen einfach, auch wenn es mehr Aufwand erfordert. Die Tests sollten symmetrisch (nach einem Muster) und präzise (jeweils ein Verhalten testen) sein. Verwenden Sie eine konsistente Namenskonvention (z. B. den TestDox-Stil). Vermeiden Sie es, den Test mit "zufälligen Details" zu überladen. Werden Sie ein Minimalist.
Abgesehen von diesen sind die meisten anderen Richtlinien, die die Arbeit mit geringem Nutzen einschränken: z. B. "Testen Sie keinen Code, den Sie nicht besitzen" (z. B. DLLs von Drittanbietern). Testen Sie nicht Getter und Setter. Behalten Sie das Kosten-Nutzen-Verhältnis oder die Fehlerwahrscheinlichkeit im Auge.
quelle
Die meisten Antworten hier beziehen sich auf Best Practices für Unit-Tests im Allgemeinen (wann, wo, warum und was), anstatt die Tests selbst zu schreiben (wie). Da die Frage im "Wie" -Teil ziemlich spezifisch zu sein schien, dachte ich, ich würde dies posten, entnommen aus einer "Brown Bag" -Präsentation, die ich in meiner Firma durchgeführt habe.
Womps 5 Gesetze zum Schreiben von Tests:
1. Verwenden Sie lange, beschreibende Testmethodennamen.
2. Schreiben Sie Ihre Tests im Arrangier- / Act- / Assert-Stil .
3. Geben Sie bei Ihren Asserts immer eine Fehlermeldung an.
4. Kommentieren Sie den Grund für den Test - wie lautet die Geschäftsannahme?
5. Jeder Test muss immer den Status einer Ressource zurücksetzen, die er berührt
quelle
Beachten Sie diese Ziele (angepasst aus dem Buch xUnit Test Patterns von Meszaros).
Einige Dinge, die dies einfacher machen:
Vergessen Sie nicht, dass Sie auch mit Ihrem xUnit-Framework Integrationstests durchführen können, aber halten Sie Integrationstests und Komponententests getrennt
quelle
Tests sollten isoliert werden. Ein Test sollte nicht von einem anderen abhängen. Darüber hinaus sollte ein Test nicht auf externen Systemen beruhen. Mit anderen Worten, testen Sie Ihren Code und nicht den Code, von dem Ihr Code abhängt. Sie können diese Interaktionen im Rahmen Ihrer Integrations- oder Funktionstests testen.
quelle
Einige Eigenschaften großartiger Unit-Tests:
Wenn ein Test fehlschlägt, sollte sofort klar sein, wo das Problem liegt. Wenn Sie den Debugger verwenden müssen, um das Problem aufzuspüren, sind Ihre Tests nicht detailliert genug. Hier hilft es, genau eine Behauptung pro Test zu haben.
Wenn Sie umgestalten, sollten keine Tests fehlschlagen.
Tests sollten so schnell ausgeführt werden, dass Sie nie zögern, sie auszuführen.
Alle Tests sollten immer bestehen; Keine nicht deterministischen Ergebnisse.
Unit-Tests sollten genau wie Ihr Produktionscode gut berücksichtigt sein.
@Alotor: Wenn Sie vorschlagen, dass eine Bibliothek nur Unit-Tests an ihrer externen API durchführen soll, bin ich anderer Meinung. Ich möchte Unit-Tests für jede Klasse, einschließlich Klassen, die ich keinen externen Anrufern aussetze. ( Wenn ich jedoch das Bedürfnis habe, Tests für private Methoden zu schreiben, muss ich eine Umgestaltung vornehmen. )
BEARBEITEN: Es gab einen Kommentar zur Duplizierung, die durch "eine Behauptung pro Test" verursacht wurde. Insbesondere wenn Sie Code zum Einrichten eines Szenarios haben und dann mehrere Zusicherungen dazu machen möchten, aber nur eine Zusicherung pro Test haben, können Sie das Setup über mehrere Tests hinweg duplizieren.
Ich gehe nicht so vor. Stattdessen verwende ich Testvorrichtungen pro Szenario . Hier ist ein grobes Beispiel:
quelle
Was Sie suchen, ist die Abgrenzung des Verhaltens der zu testenden Klasse.
Die grundlegende Absicht ist es, Ihr Vertrauen in das Verhalten der Klasse zu erhöhen.
Dies ist besonders nützlich, wenn Sie Ihren Code umgestalten möchten. Martin Fowler hat auf seiner Website einen interessanten Artikel zum Thema Testen.
HTH.
Prost,
rauben
quelle
Test sollte ursprünglich fehlschlagen. Dann sollten Sie den Code schreiben, mit dem sie bestanden werden. Andernfalls besteht die Gefahr, dass Sie einen Test schreiben, der fehlerhaft ist und immer bestanden wird.
quelle
Ich mag das Akronym Right BICEP aus dem oben genannten Buch Pragmatic Unit Testing :
Persönlich denke ich, dass Sie ziemlich weit kommen können, indem Sie überprüfen, ob Sie die richtigen Ergebnisse erhalten (1 + 1 sollte 2 in einer Additionsfunktion zurückgeben) und alle denkbaren Randbedingungen ausprobieren (z. B. zwei Zahlen verwenden, von denen die Summe ist größer als der ganzzahlige Maximalwert in der Add-Funktion) und erzwingt Fehlerbedingungen wie Netzwerkfehler.
quelle
Gute Tests müssen wartbar sein.
Ich habe nicht ganz herausgefunden, wie das für komplexe Umgebungen geht.
Alle Lehrbücher beginnen sich zu lösen, wenn Ihre Codebasis in die Hunderte von 1000 oder Millionen von Codezeilen reicht.
Eine gute Architektur kann einen Teil der Interaktionsexplosion kontrollieren, aber wenn Systeme komplexer werden, wächst zwangsläufig das automatisierte Testsystem mit.
Hier müssen Sie sich mit Kompromissen auseinandersetzen:
Sie müssen sich auch entscheiden:
Wo speichern Sie Testfälle in Ihrer Codebasis?
Ich könnte für immer weitermachen, aber mein Punkt ist:
Tests müssen wartbar sein.
quelle
Ich habe diese Prinzipien vor einiger Zeit in diesem Artikel des MSDN-Magazins behandelt, den ich für wichtig halte, damit jeder Entwickler ihn lesen kann.
Ich definiere "gute" Komponententests so, wenn sie die folgenden drei Eigenschaften besitzen:
quelle
quelle
Jay Fields hat viele gute Ratschläge zum Schreiben von Unit-Tests und es gibt einen Beitrag, in dem er die wichtigsten Ratschläge zusammenfasst . Dort lesen Sie, dass Sie kritisch über Ihren Kontext nachdenken und beurteilen sollten, ob der Rat für Sie wert ist. Sie erhalten hier eine Menge erstaunlicher Antworten, aber es liegt an Ihnen, zu entscheiden, welche für Ihren Kontext am besten geeignet ist. Probieren Sie sie aus und überarbeiten Sie sie einfach, wenn es für Sie schlecht riecht.
Mit freundlichen Grüßen
quelle
Gehen Sie niemals davon aus, dass eine triviale 2-Zeilen-Methode funktioniert. Das Schreiben eines schnellen Komponententests ist die einzige Möglichkeit, um zu verhindern, dass der fehlende Nulltest, das falsch platzierte Minuszeichen und / oder der subtile Scoping-Fehler Sie beißen, unweigerlich, wenn Sie noch weniger Zeit haben, sich damit zu befassen als jetzt.
quelle
Ich stimme der Antwort "A TRIP" zu, außer dass sich Tests aufeinander verlassen SOLLTEN !!!
Warum?
DRY - Wiederholen Sie sich nicht - gilt auch für Tests! Testabhängigkeiten können helfen, 1) Setup-Zeit zu sparen, 2) Fixture-Ressourcen zu sparen und 3) Fehler zu lokalisieren. Natürlich nur, wenn Ihr Testframework erstklassige Abhängigkeiten unterstützt. Ansonsten gebe ich zu, dass sie schlecht sind.
Follow-up http://www.iam.unibe.ch/~scg/Research/JExample/
quelle
Oft basieren Unit-Tests auf Scheinobjekten oder Scheindaten. Ich schreibe gerne drei Arten von Unit-Tests:
Es geht darum zu vermeiden, alles wiederzugeben , um alle Funktionen testen zu können.
quelle
Denken Sie an die beiden Testarten und behandeln Sie sie unterschiedlich - Funktionstests und Leistungstests.
Verwenden Sie jeweils unterschiedliche Eingaben und Metriken. Möglicherweise müssen Sie für jeden Testtyp eine andere Software verwenden.
quelle
Ich verwende eine konsistente Testbenennungskonvention, die von Roy Osheroves Unit Test Naming-Standards beschrieben wird. Jede Methode in einer bestimmten Testfallklasse hat den folgenden Namensstil MethodUnderTest_Scenario_ExpectedResult.
Der erste Abschnitt mit dem Testnamen ist der Name der Methode im zu testenden System.
Als nächstes folgt das spezifische Szenario, das getestet wird.
Schließlich sind die Ergebnisse dieses Szenarios.
Jeder Abschnitt verwendet Großbuchstaben und wird durch eine Unterpunktzahl begrenzt.
Ich habe dies als nützlich empfunden, wenn ich den Test durchführe. Die Tests werden nach dem Namen der zu testenden Methode gruppiert. Und eine Konvention ermöglicht es anderen Entwicklern, die Testabsicht zu verstehen.
Ich füge auch Parameter an den Methodennamen an, wenn die zu testende Methode überladen wurde.
quelle