Wie viele Tests pro Methode?
Nun, das theoretische und höchst unpraktische Maximum ist die N-Pfad-Komplexität (vorausgesetzt, die Tests decken alle verschiedene Wege durch den Code ab;)). Das Minimum ist EINS !. Gemäß der öffentlichen Methode testet er keine Implementierungsdetails, sondern nur das externe Verhalten einer Klasse (Rückgabewerte und Aufrufen anderer Objekte).
Sie zitieren:
* Und der Gedanke, jede Ihrer Methoden mit einer eigenen Testmethode (in einer 1: 1-Beziehung) zu testen, ist lächerlich. *
und dann fragen:
Wenn es also lächerlich ist, für jede Methode einen Test zu erstellen, wie / wann haben Sie dann ausgewählt, wofür Sie Tests schreiben?
Aber ich denke, Sie haben den Autor hier falsch verstanden:
Die Idee, one test method
Per zu haben, one method in the class to test
nennt der Autor "lächerlich".
(Zumindest für mich) Es geht nicht um "weniger", es geht um "mehr"
Lassen Sie mich so umformulieren, als hätte ich ihn verstanden:
Und der Gedanke, jede Ihrer Methoden mit NUR EINER METHODE (einer eigenen Testmethode in einer 1: 1-Beziehung) zu testen, wird lächerlich sein.
So zitieren Sie Ihr Angebot erneut:
Wenn Sie feststellen, dass es nur darum geht, Verhalten zu spezifizieren und keine Tests zu schreiben, ändert sich Ihre Sichtweise.
Wenn Sie TDD üben, denken Sie nicht :
Ich habe eine Methode calculateX($a, $b);
und es braucht einen Test testCalculcateX
, der ALLES über die Methode testet.
Was TDD Ihnen sagt, ist darüber nachzudenken, was Ihr Code tun sollte :
Ich muss den größeren von zwei Werten berechnen ( erster Testfall! ), Aber wenn $ a kleiner als Null ist, sollte es einen Fehler erzeugen ( zweiter Testfall! ) Und wenn $ b kleiner als Null ist, sollte es ... ( dritter Testfall! ) und so weiter.
Sie möchten Verhalten testen, nicht nur einzelne Methoden ohne Kontext.
Auf diese Weise erhalten Sie eine Testsuite, die Dokumentation für Ihren Code ist und WIRKLICH erklärt, was von ihm erwartet wird, vielleicht sogar warum :)
Wie entscheiden Sie, für welchen Teil Ihres Codes Sie Komponententests erstellen?
Nun, alles, was im Endlager oder irgendwo in der Nähe der Produktion landet, muss getestet werden. Ich glaube nicht, dass der Autor Ihrer Zitate damit nicht einverstanden wäre, wie ich oben dargelegt habe.
Wenn Sie keinen Test dafür haben, wird es viel schwieriger (teurer), den Code zu ändern, besonders wenn Sie die Änderung nicht vornehmen.
TDD ist eine Möglichkeit, um sicherzustellen, dass Sie Tests für ALLES haben, aber solange Sie die Tests schreiben, ist es in Ordnung. Normalerweise hilft es, sie am selben Tag zu schreiben, da Sie es später nicht tun werden, oder? :)
Antwort auf Kommentare:
Eine anständige Anzahl von Methoden kann in einem bestimmten Kontext nicht getestet werden, da sie entweder von anderen Methoden abhängen oder von diesen abhängig sind
Nun, diese Methoden können drei Dinge aufrufen:
Öffentliche Methoden anderer Klassen
Wir können andere Klassen verspotten, also haben wir dort den Status definiert. Wir haben die Kontrolle über den Kontext, so dass dies kein Problem ist.
* Geschützte oder private Methoden auf dem gleichen *
Alles, was nicht Teil der öffentlichen API einer Klasse ist, wird normalerweise nicht direkt getestet.
Sie möchten das Verhalten und nicht die Implementierung testen, und wenn eine Klasse alles tut, funktioniert dies in einer großen öffentlichen Methode oder in vielen kleineren geschützten Methoden, die aufgerufen werden, in der Implementierung . Sie möchten in der Lage sein, diese geschützten Methoden ZU ÄNDERN, OHNE Ihre Tests zu berühren. Denn Ihre Tests brechen ab, wenn Ihr Code das Verhalten ändert! Dafür sind deine Tests da, um dir zu sagen, wann du etwas kaputt machst :)
Öffentliche Methoden für dieselbe Klasse
Das kommt nicht sehr oft vor, oder? Und wenn es wie im folgenden Beispiel aussieht, gibt es ein paar Möglichkeiten, damit umzugehen:
$stuff = new Stuff();
$stuff->setBla(12);
$stuff->setFoo(14);
$stuff->execute();
Dass die Setter existieren und nicht Teil der Signatur der Execute-Methode sind, ist ein anderes Thema;)
Was wir hier testen können, ist, ob Executes explodieren, wenn wir die falschen Werte einstellen. Das setBla
löst eine Ausnahme aus, wenn Sie eine Zeichenfolge übergeben, die separat getestet werden kann. Wenn Sie jedoch testen möchten, dass diese beiden zulässigen Werte (12 und 14) nicht ZUSAMMEN (aus welchem Grund auch immer) funktionieren, ist dies nur ein Testfall.
Wenn Sie eine "gute" Testsuite wollen, können Sie in PHP vielleicht (!) Eine @covers Stuff::execute
Anmerkung hinzufügen , um sicherzustellen, dass Sie nur Code-Coverage für diese Methode generieren, und die anderen Dinge, die gerade eingerichtet werden, müssen separat getestet werden (noch einmal, wenn Du willst das).
Der Punkt ist also: Vielleicht müssen Sie zuerst einen Teil der umgebenden Welt erstellen, aber Sie sollten in der Lage sein, aussagekräftige Testfälle zu schreiben, die normalerweise nur eine oder vielleicht zwei reale Funktionen umfassen (Setter zählen hier nicht). Der Rest kann verspottet oder zuerst getestet und dann als Referenz herangezogen werden (siehe @depends
).
* Hinweis: Die Frage wurde von SO migriert und betraf ursprünglich PHP / PHPUnit. Aus diesem Grund stammen der Beispielcode und die Referenzen aus der PHP-Welt. Ich denke, dies gilt auch für andere Sprachen, da sich phpunit nicht wesentlich von anderen xUnit unterscheidet Testen von Frameworks.