Was macht einen guten Unit-Test aus? [geschlossen]

97

Ich bin sicher, dass die meisten von Ihnen viele automatisierte Tests schreiben und dass Sie auch beim Testen von Einheiten auf einige häufige Fallstricke gestoßen sind.

Meine Frage ist, ob Sie beim Schreiben von Tests Verhaltensregeln befolgen, um künftige Probleme zu vermeiden. Genauer gesagt: Was sind die Eigenschaften guter Komponententests oder wie schreiben Sie Ihre Tests?

Sprachunabhängige Vorschläge sind erwünscht.

Spoike
quelle

Antworten:

93

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.

Gishu
quelle
Wir sind uns vielleicht nicht einig über die Verwendung von Mocks, aber dies war eine sehr schöne Zusammenfassung der Best Practices für Unit-Tests.
Justin Standard
Ich werde dieses als Antwort dann anstoßen, weil ich das Akronym "A TRIP" nützlich finde.
Spoike
3
Ich stimme größtenteils zu, möchte aber darauf hinweisen, dass das Testen von Code, den Sie nicht besitzen, einen Vorteil hat ... Sie testen, ob er Ihren Anforderungen entspricht. Wie können Sie sonst sicher sein, dass ein Upgrade Ihre Systeme nicht beschädigt? (Aber natürlich sollten Sie dabei das Kosten-Nutzen-Verhältnis berücksichtigen.)
Desillusioniert am
@Craig - Ich glaube, Sie beziehen sich auf Regressionstests (auf Schnittstellenebene) (oder in einigen Fällen auf Lerntests), die das Verhalten dokumentieren, von dem Sie abhängen. Ich würde keine "Unit" -Tests für Code von Drittanbietern schreiben, weil a. Der Anbieter weiß mehr über diesen Code als ich. b. Der Anbieter ist nicht verpflichtet, eine bestimmte Implementierung beizubehalten. Ich kontrolliere keine Änderungen an dieser Codebasis und möchte meine Zeit nicht damit verbringen, fehlerhafte Tests mit einem Upgrade zu beheben. Also würde ich lieber einige Regressionstests auf hoher Ebene für das Verhalten codieren, das ich verwende (und benachrichtigt werden möchte, wenn es kaputt ist)
Gishu
@ Gishu: Ja, absolut! Die Tests dürfen nur auf Schnittstellenebene durchgeführt werden. In der Tat sollten Sie höchstens die Funktionen testen, die Sie tatsächlich verwenden. Darüber hinaus bei der Auswahl, mit was diese Tests geschrieben werden sollen; Ich habe festgestellt, dass die einfachen, einfachen "Unit" -Test-Frameworks normalerweise perfekt zur Rechnung passen.
Desillusioniert
42
  1. Schreiben Sie keine riesigen Tests. Machen Sie, wie die 'Einheit' in 'Einheitentest' andeutet, jede so atomar und isoliert wie möglich. Wenn Sie müssen, erstellen Sie Voraussetzungen mit Scheinobjekten, anstatt zu viel von der typischen Benutzerumgebung manuell neu zu erstellen.
  2. Testen Sie keine Dinge, die offensichtlich funktionieren. Vermeiden Sie es, die Klassen von einem Drittanbieter zu testen, insbesondere von denjenigen, die die Kern-APIs des Frameworks bereitstellen, in dem Sie codieren. Testen Sie beispielsweise nicht, ob Sie der Hashtable-Klasse des Anbieters ein Element hinzufügen.
  3. Verwenden Sie ein Tool zur Codeabdeckung wie NCover, um Randfälle zu ermitteln, die Sie noch nicht getestet haben.
  4. Versuchen Sie, den Test vor der Implementierung zu schreiben . Stellen Sie sich den Test eher als eine Spezifikation vor, die Ihre Implementierung einhalten wird. Vgl. auch verhaltensorientierte Entwicklung, ein spezifischerer Zweig der testgetriebenen Entwicklung.
  5. Seien Sie konsequent. Wenn Sie nur Tests für einen Teil Ihres Codes schreiben, ist dies kaum sinnvoll. Wenn Sie in einem Team arbeiten und einige oder alle anderen keine Tests schreiben, ist dies auch nicht sehr nützlich. Überzeugen Sie sich und alle anderen von der Wichtigkeit (und den zeitsparenden Eigenschaften) des Testens oder stören Sie sich nicht.
Sören Kuklau
quelle
1
Gute Antwort. Aber es ist nicht so schlimm, wenn Sie nicht für alles in einer Lieferung einen Unit-Test durchführen. Sicher ist es vorzuziehen, aber es muss ein Gleichgewicht und Pragmatismus geben. Betreff: Ihre Kollegen an Bord holen; Manchmal muss man es nur tun, um Wert zu demonstrieren und als Bezugspunkt.
Martin Clarke
1
Genau. Auf lange Sicht müssen Sie sich jedoch darauf verlassen können, dass Tests vorhanden sind, dh Sie können davon ausgehen, dass häufige Fallstricke von ihnen erfasst werden. Andernfalls werden die Vorteile massiv gemindert.
Sören Kuklau
2
"Wenn Sie nur Tests für einen Teil Ihres Codes schreiben, ist dies kaum sinnvoll." Ist das wirklich der Fall? Ich habe Projekte mit 20% Codeabdeckung (entscheidend / fehleranfällig) und sie haben mir massiv geholfen, und Projekte sind auch in Ordnung.
dr. böse
1
Ich stimme Slough zu. Selbst wenn es nur wenige Tests gibt, da sie gut geschrieben und isoliert genug sind, helfen sie enorm.
Spoike
41

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.

   - Map_DefaultConstructorShouldCreateEmptyGisMap()
   - ShouldAlwaysDelegateXMLCorrectlyToTheCustomHandlers()
   - Dog_Object_Should_Eat_Homework_Object_When_Hungry()

2. Schreiben Sie Ihre Tests im Arrangier- / Act- / Assert-Stil .

  • Während diese Organisationsstrategie schon seit einiger Zeit existiert und viele Dinge nennt, war die Einführung des Akronyms "AAA" in letzter Zeit eine großartige Möglichkeit, dies zu vermitteln. Wenn Sie alle Ihre Tests mit dem AAA-Stil in Einklang bringen, sind sie leicht zu lesen und zu warten.

3. Geben Sie bei Ihren Asserts immer eine Fehlermeldung an.

Assert.That(x == 2 && y == 2, "An incorrect number of begin/end element 
processing events was raised by the XElementSerializer");
  • Eine einfache, aber lohnende Übung, die in Ihrer Runner-Anwendung deutlich macht, was fehlgeschlagen ist. Wenn Sie keine Nachricht angeben, wird in Ihrer Fehlerausgabe normalerweise so etwas wie "Erwartet wahr, war falsch" angezeigt, sodass Sie den Test tatsächlich lesen müssen, um herauszufinden, was falsch ist.

4. Kommentieren Sie den Grund für den Test - wie lautet die Geschäftsannahme?

  /// A layer cannot be constructed with a null gisLayer, as every function 
  /// in the Layer class assumes that a valid gisLayer is present.
  [Test]
  public void ShouldNotAllowConstructionWithANullGisLayer()
  {
  }
  • Dies mag offensichtlich erscheinen, aber diese Vorgehensweise schützt die Integrität Ihrer Tests vor Personen, die den Grund für den Test überhaupt nicht verstehen. Ich habe gesehen, dass viele Tests entfernt oder geändert wurden, die vollkommen in Ordnung waren, einfach weil die Person die Annahmen, die der Test verifizierte, nicht verstand.
  • Wenn der Test trivial ist oder der Methodenname ausreichend beschreibend ist, kann es zulässig sein, den Kommentar wegzulassen.

5. Jeder Test muss immer den Status einer Ressource zurücksetzen, die er berührt

  • Verwenden Sie nach Möglichkeit Mocks, um den Umgang mit realen Ressourcen zu vermeiden.
  • Die Bereinigung muss auf Testebene erfolgen. Tests dürfen sich nicht auf die Reihenfolge der Ausführung verlassen.
womp
quelle
2
+1 wegen Punkt 1, 2 und 5 sind wichtig. 3 und 4 scheinen für Komponententests ziemlich übertrieben zu sein, wenn Sie bereits beschreibende Testmethodennamen verwenden, aber ich empfehle die Dokumentation von Tests, wenn sie einen großen Umfang haben (Funktions- oder Abnahmetests).
Spoike
+1 für bodenständige und praktische Kenntnisse und Beispiele
Phil
17

Beachten Sie diese Ziele (angepasst aus dem Buch xUnit Test Patterns von Meszaros).

  • Tests sollten das Risiko verringern, nicht einführen.
  • Tests sollten einfach durchzuführen sein.
  • Tests sollten einfach zu warten sein, wenn sich das System um sie herum entwickelt

Einige Dinge, die dies einfacher machen:

  • Tests sollten nur aus einem Grund fehlschlagen.
  • Tests sollten nur eines testen
  • Minimieren Sie Testabhängigkeiten (keine Abhängigkeiten von Datenbanken, Dateien, Benutzeroberflächen usw.)

Vergessen Sie nicht, dass Sie auch mit Ihrem xUnit-Framework Integrationstests durchführen können, aber halten Sie Integrationstests und Komponententests getrennt

Mendelt
quelle
Ich denke, Sie meinten, Sie hätten sich aus dem Buch "xUnit Test Patterns" von Gerard Meszaros angepasst. xunitpatterns.com
Spoike
Ja, du hast recht. Ich werde das in der Post
klären
Hervorragende Punkte. Unit-Tests können sehr nützlich sein, aber es ist sehr wichtig, nicht in die Falle komplexer, voneinander abhängiger Unit-Tests zu geraten, die eine enorme Steuer für alle Versuche verursachen, das System zu ändern.
Wedge
9

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.

Gehackt
quelle
9

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:

[TestFixture]
public class StackTests
{
    [TestFixture]
    public class EmptyTests
    {
        Stack<int> _stack;

        [TestSetup]
        public void TestSetup()
        {
            _stack = new Stack<int>();
        }

        [TestMethod]
        [ExpectedException (typeof(Exception))]
        public void PopFails()
        {
            _stack.Pop();
        }

        [TestMethod]
        public void IsEmpty()
        {
            Assert(_stack.IsEmpty());
        }
    }

    [TestFixture]
    public class PushedOneTests
    {
        Stack<int> _stack;

        [TestSetup]
        public void TestSetup()
        {
            _stack = new Stack<int>();
            _stack.Push(7);
        }

        // Tests for one item on the stack...
    }
}
Jay Bazuzi
quelle
Ich bin nicht einverstanden mit nur einer Behauptung pro Test. Je mehr Aussagen Sie in einem Test haben, desto weniger Testfälle können Sie ausschneiden und einfügen. Ich glaube, ein Testfall sollte sich auf ein Szenario oder einen Codepfad konzentrieren und die Aussagen sollten sich aus allen Annahmen und Anforderungen ergeben, um dieses Szenario zu erfüllen.
Lucas B
Ich denke, wir sind uns einig, dass DRY für Unit-Tests gilt. Wie gesagt, "Unit-Tests sollten gut berücksichtigt werden". Es gibt jedoch mehrere Möglichkeiten, die Duplizierung aufzulösen. Wie Sie bereits erwähnt haben, besteht ein Unit-Test darin, zuerst den zu testenden Code aufzurufen und dann mehrmals zu bestätigen. Eine Alternative besteht darin, ein neues "Testgerät" für das Szenario zu erstellen, das den zu testenden Code während eines Initialisierungs- / Setup-Schritts aufruft und dann eine Reihe von Komponententests durchführt, die einfach bestätigt werden.
Jay Bazuzi
Meine Faustregel lautet: Wenn Sie Copy-Paste verwenden, machen Sie etwas falsch. Eines meiner Lieblingssprüche ist "Copy-Paste ist kein Designmuster." Ich stimme auch zu, dass eine Behauptung pro Testeinheit im Allgemeinen eine gute Idee ist, aber ich bestehe nicht immer darauf. Ich mag den allgemeineren "Test eins pro Testeinheit". Dies führt normalerweise zu einer Behauptung pro Testeinheit.
Jon Turner
7

Was Sie suchen, ist die Abgrenzung des Verhaltens der zu testenden Klasse.

  1. Überprüfung des erwarteten Verhaltens.
  2. Überprüfung von Fehlerfällen.
  3. Abdeckung aller Codepfade innerhalb der Klasse.
  4. Ausübung aller Mitgliedsfunktionen innerhalb der 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

Rob Wells
quelle
Rob - mechanisch ist das gut, aber es verfehlt die Absicht. Warum hast du das alles gemacht? Wenn Sie so denken, kann dies anderen auf dem Weg zu TDD helfen.
Mark Levison
7

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.

Streit
quelle
@Rismo Nicht exklusiv an sich. Per Definition ist das, was Quarrelsome hier geschrieben hat, exklusiv für die "Test First" -Methode, die Teil von TDD ist. TDD berücksichtigt auch das Refactoring. Die "Smarty Pants" -Definition, die ich gelesen habe, ist TDD = Test First + Refactor.
Spoike
Ja, es muss nicht TDD sein, stellen Sie nur sicher, dass Ihr Test zuerst fehlschlägt. Anschließend den Rest verdrahten. Dies tritt am häufigsten bei TDD auf, Sie können es jedoch auch anwenden, wenn Sie TDD nicht verwenden.
Quibblesome
6

Ich mag das Akronym Right BICEP aus dem oben genannten Buch Pragmatic Unit Testing :

  • Richtig : Sind die Ergebnisse richtig ?
  • B : Sind alle b oundary Bedingungen korrekt?
  • I : Können wir überprüfen i nverse Beziehungen?
  • C : Können wir c ross-Prüfergebnissen mit anderen Mitteln?
  • E : Können wir zwingen e rror Bedingungen zu geschehen?
  • P : Sind p Merkmale erformance in Grenzen?

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.

Peter Evjan
quelle
6

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.

  • Teaminteraktionen explodieren
  • Anzahl der Testfälle explodiert
  • Wechselwirkungen zwischen Komponenten explodieren.
  • Die Zeit zum Erstellen aller Unittests wird zu einem wesentlichen Teil der Erstellungszeit
  • Eine API-Änderung kann sich auf Hunderte von Testfällen auswirken. Obwohl die Änderung des Produktionscodes einfach war.
  • Die Anzahl der Ereignisse, die erforderlich sind, um Prozesse in den richtigen Zustand zu versetzen, erhöht sich, was wiederum die Testausführungszeit erhöht.

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:

  • Nur die externe API testen, andernfalls führt das Refactoring von Interna zu erheblichen Nacharbeiten an Testfällen.
  • Das Einrichten und Herunterfahren jedes Tests wird komplizierter, da ein gekapseltes Subsystem mehr Status behält.
  • Die nächtliche Kompilierung und automatisierte Testausführung wächst auf Stunden.
  • Höhere Kompilierungs- und Ausführungszeiten bedeuten, dass Designer nicht alle Tests ausführen oder nicht ausführen
  • Um die Ausführungszeiten der Tests zu verkürzen, sollten Sie die Sequenzierung von Tests in Betracht ziehen, um das Ein- und Ausschalten zu reduzieren

Sie müssen sich auch entscheiden:

Wo speichern Sie Testfälle in Ihrer Codebasis?

  • Wie dokumentieren Sie Ihre Testfälle?
  • Können Testvorrichtungen wiederverwendet werden, um die Wartung von Testfällen zu sparen?
  • Was passiert, wenn eine nächtliche Testfallausführung fehlschlägt? Wer macht die Triage?
  • Wie pflegen Sie die Scheinobjekte? Wenn Sie über 20 Module verfügen, die alle ihre eigene Variante einer Scheinprotokollierungs-API verwenden, wird die API schnell geändert. Nicht nur die Testfälle ändern sich, sondern auch die 20 Scheinobjekte. Diese 20 Module wurden über mehrere Jahre von vielen verschiedenen Teams geschrieben. Es ist ein klassisches Wiederverwendungsproblem.
  • Einzelpersonen und ihre Teams verstehen den Wert automatisierter Tests, die ihnen einfach nicht gefallen, wie das andere Team dies tut. :-)

Ich könnte für immer weitermachen, aber mein Punkt ist:

Tests müssen wartbar sein.

DanM
quelle
5

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:

  • Sie sind lesbar (Benennung, Behauptungen, Variablen, Länge, Komplexität ..)
  • Sie sind wartbar (keine Logik, nicht überbestimmt, zustandsbasiert, überarbeitet).
  • Sie sind vertrauenswürdig (testen Sie das Richtige, isoliert, nicht Integrationstests ..)
RoyOsherove
quelle
Roy, ich stimme voll und ganz zu. Diese Dinge sind so viel wichtiger als die Abdeckung von Randfällen.
Matt Hinze
vertrauenswürdig - ausgezeichneter Punkt!
Ratkok
4
  • Unit Testing testet nur die externe API Ihrer Unit. Sie sollten das interne Verhalten nicht testen.
  • Jeder Test eines TestCase sollte eine (und nur eine) Methode innerhalb dieser API testen.
    • Zusätzliche Testfälle sollten für Fehlerfälle enthalten sein.
  • Testen Sie die Abdeckung Ihrer Tests: Sobald eine Einheit getestet wurde, sollten die 100% der Zeilen in dieser Einheit ausgeführt worden sein.
Alotor
quelle
2

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

marcospereira
quelle
1

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.

Joel in Gö
quelle
1

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/

akuhn
quelle
Ich stimme dir zu. TestNG ist ein weiteres Framework, in dem Abhängigkeiten problemlos zulässig sind.
Davide
0

Oft basieren Unit-Tests auf Scheinobjekten oder Scheindaten. Ich schreibe gerne drei Arten von Unit-Tests:

  • "vorübergehende" Unit-Tests: Sie erstellen ihre eigenen Scheinobjekte / Daten und testen damit ihre Funktion, zerstören aber alles und hinterlassen keine Spuren (wie keine Daten in einer Testdatenbank).
  • "persistenter" Komponententest: Sie testen Funktionen in Ihrem Code und erstellen Objekte / Daten, die später von erweiterten Funktionen für ihren eigenen Komponententest benötigt werden (wobei vermieden wird, dass diese erweiterten Funktionen jedes Mal neu erstellt werden, wenn ihre eigenen Scheinobjekte / Daten erstellt werden).
  • "Persistent-basierte" Unit-Tests: Unit-Tests mit Scheinobjekten / Daten, die bereits von den persistenten Unit-Tests vorhanden sind (weil sie in einer anderen Unit-Testsitzung erstellt wurden).

Es geht darum zu vermeiden, alles wiederzugeben , um alle Funktionen testen zu können.

  • Ich führe die dritte Art sehr oft aus, weil alle Scheinobjekte / Daten bereits vorhanden sind.
  • Ich führe die zweite Art aus, wenn mein Modell wechselt.
  • Ich führe den ersten aus, um ab und zu die grundlegenden Funktionen zu überprüfen, um grundlegende Regressionen zu überprüfen.
VonC
quelle
0

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.

Techboy
quelle
Was ist dann mit Unit-Tests?
Spoike
0

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.

Yack
quelle