Wenn ich Unit-Tests schreibe, habe ich immer versucht, eine einzige Bestätigung pro Test zu erstellen, um das Debuggen zu vereinfachen, wenn Tests fehlschlagen. Wenn ich mich jedoch an diese Regel halte, habe ich das Gefühl, dass ich in jedem Test ständig denselben Code kopiere. Wenn ich mehr Tests habe, wird es schwieriger, zum Lesen und Verwalten zurückzukehren.
Verstößt das Testen mit einer Behauptung gegen DRY?
Und gibt es eine gute Regel, um ein gutes Gleichgewicht zu finden, beispielsweise nur einen Test pro Methode ? *
* Mir ist klar, dass es wahrscheinlich keine einheitliche Lösung dafür gibt, aber gibt es einen empfohlenen Weg, dies zu erreichen?
testing
unit-testing
dry
Korey Hinton
quelle
quelle
Antworten:
Richtige Komponententests haben eine Namenskonvention , mit der Sie sofort feststellen können, was fehlgeschlagen ist:
Aus diesem Grund haben Sie eine Zusicherung pro Test, sodass jede Methode (und ihr Name) der Bedingung entspricht, die Sie geltend machen.
Wie Sie richtig betont haben, wird jeder neue Test einen ähnlichen Setup-Code haben. Wie bei jedem Code können Sie den allgemeinen Code in eine eigene Methode umgestalten, um die Duplizierung zu reduzieren oder zu beseitigen und Ihren Code trockener zu machen. Einige Test-Frameworks wurden speziell entwickelt, damit Sie diesen Setup-Code an einem Ort ablegen können .
In TDD ist kein Test YAGNI, da Sie Tests nur basierend auf den Anforderungen Ihres Codes schreiben. Wenn Sie es nicht brauchen, werden Sie den Test nicht schreiben.
quelle
Nein, aber es fördert Verstöße.
Trotzdem tendiert gutes objektorientiertes Design dazu, für Unit-Tests aus dem Fenster zu gehen - meistens aus gutem Grund. Es ist wichtiger, dass Komponententests voneinander isoliert sind, damit der Test isoliert abgefragt und bei Bedarf mit der Gewissheit behoben werden kann, dass Sie andere Tests nicht brechen. Grundsätzlich ist diese Testkorrektheit und Lesbarkeit wichtiger als ihre Größe oder Wartbarkeit.
Ehrlich gesagt war ich aus den von Ihnen beschriebenen Gründen noch nie ein Fan der einen Assert-per-Test-Regel: Sie führt zu einer Menge Code auf dem Boilerplate, der schwer zu lesen, leicht zu verfälschen und schwer zu reparieren ist, wenn Sie den Refactor durchführen (was Sie dazu bringt, weniger umzugestalten).
Wenn eine Funktion eine Liste von "foo" und "bar" für eine bestimmte Eingabe zurückgeben soll, ist es jedoch völlig in Ordnung, zwei Asserts zu verwenden, um zu überprüfen, ob beide in der Ergebnismenge enthalten sind. Sie geraten in Schwierigkeiten, wenn ein einzelner Test zwei Eingänge oder zwei Nebenwirkungen überprüft und Sie nicht wissen, welcher der beiden den Fehler verursacht hat.
Ich betrachte es als eine Variation des Einzelverantwortungsprinzips: Es sollte nur eines geben, das dazu führen kann, dass ein Test fehlschlägt, und in einer idealen Welt sollte diese Änderung nur einen Test brechen.
Aber am Ende ist es ein Kompromiss. Ist es wahrscheinlicher, dass Sie mehr Zeit damit verbringen, den gesamten Code zum Kopieren und Einfügen zu verwalten, oder werden Sie mehr Zeit damit verbringen, nach Ursachen zu suchen, wenn Tests durch mehrere Quellen unterbrochen werden könnten? Solange Sie einige Tests schreiben, spielt es wahrscheinlich keine Rolle. Trotz meiner Verachtung für Single-Assert-Tests neige ich dazu, mich auf die Seite weiterer Tests zu stellen. Ihr Kilometerstand kann variieren.
quelle
Nein. Dies scheint genau so zu sein, wie Sie es tun. Es sei denn, Sie haben eine bemerkenswerte Referenz gefunden, in der behauptet wird, dies sei eine gute Praxis.
Verwenden Sie ein Testgerät (obwohl in der XUnit-Terminologie der Satz von Tests, das Einrichten und Herunterfahren das Gerät ist), dh einige Einstellungen oder Beispiele, die für alle Ihre Tests gelten.
Verwenden Sie Methoden, wie Sie es normalerweise tun würden, um Ihren Code zu strukturieren. Bei Refactoring-Tests gilt nicht der übliche TDD- Rot-Grün-Refactor , sondern "Refactoring in the Red". Das ist,
Auf diese Weise wissen Sie, dass die Tests immer noch positive und negative Ergebnisse liefern.
Es gibt verschiedene Standardformate für Tests. Beispiel: Anordnen, Handeln, Bestätigen oder Gegeben wann, dann (BDD) . Verwenden Sie für jeden Schritt eine separate Funktion. Sie sollten in der Lage sein, die Funktion zum Reduzieren der Kesselplatte aufzurufen.
quelle