Ich habe ein Stück Code, das ungefähr so aussieht:
function bool PassesBusinessRules()
{
bool meetsBusinessRules = false;
if (PassesBusinessRule1
&& PassesBusinessRule2
&& PassesBusinessRule3)
{
meetsBusinessRules= true;
}
return meetsBusinessRules;
}
Ich glaube, es sollte vier Unit-Tests für diese bestimmte Funktion geben. Drei, um jede der Bedingungen in der if-Anweisung zu testen und sicherzustellen, dass sie false zurückgibt. Und ein weiterer Test, der sicherstellt, dass die Funktion true zurückgibt.
Frage: Sollte es stattdessen zehn Unit-Tests geben? Neun, die jeden der möglichen Fehlerpfade überprüft. IE:
- Falsch Falsch Falsch
- Falsch Falsch Richtig
- Falsch Richtig Falsch
Und so weiter für jede mögliche Kombination.
Ich denke, das ist übertrieben, aber einige der anderen Mitglieder in meinem Team tun es nicht. Wenn BusinessRule1 ausfällt, sollte es immer false zurückgeben. Es spielt keine Rolle, ob es zuerst oder zuletzt überprüft wurde.
unit-testing
bwalk2895
quelle
quelle
Antworten:
Formal haben diese Arten der Berichterstattung Namen.
Erstens gibt es eine Prädikatabdeckung : Sie möchten einen Testfall, der die if-Anweisung wahr macht, und einen, der sie falsch macht. Die Einhaltung dieser Abdeckung ist wahrscheinlich eine Grundvoraussetzung für eine gute Testsuite.
Dann gibt es Bedingungsabdeckung : Hier möchten Sie testen, dass jede Unterbedingung im if den Wert true und false hat. Dies führt offensichtlich zu mehr Tests, behebt jedoch in der Regel mehr Fehler. Daher ist es oft eine gute Idee, diese in Ihre Testsuite aufzunehmen, wenn Sie Zeit haben.
Das am weitesten fortgeschrittene Erfassungskriterium wird normalerweise als kombinatorische Bedingungserfassung bezeichnet : Hier besteht das Ziel darin, einen Testfall zu erstellen, der alle möglichen Kombinationen von Booleschen Werten in Ihrem Test durchläuft .
Ist dies besser als einfaches Prädikat oder Bedingungsüberdeckung? In Bezug auf die Berichterstattung natürlich. Aber es ist nicht kostenlos. Bei der Testwartung sind die Kosten sehr hoch. Aus diesem Grund kümmern sich die meisten Menschen nicht um eine vollständige kombinatorische Abdeckung. Normalerweise ist das Testen aller Zweige (oder aller Bedingungen) gut genug, um Fehler zu erkennen. Das Hinzufügen der zusätzlichen Tests für kombinatorische Tests führt normalerweise nicht zu mehr Fehlern, erfordert jedoch viel Aufwand beim Erstellen und Verwalten. Aufgrund des zusätzlichen Aufwands lohnt sich diese Auszahlung normalerweise nicht, daher würde ich sie nicht empfehlen.
Ein Teil dieser Entscheidung sollte davon abhängen, wie riskant Sie diesen Code finden. Wenn es viel Raum zum Scheitern gibt, lohnt es sich zu testen. Wenn es etwas stabil ist und sich nicht viel ändert, sollten Sie Ihre Testbemühungen auf andere Bereiche konzentrieren.
quelle
Letztendlich hängt es von Ihnen (r Team), dem Code und der spezifischen Projektumgebung ab. Es gibt keine universelle Regel. Sie (Ihr Team) sollten so viele Tests schreiben, wie Sie benötigen, um sich sicher zu sein, dass der Code tatsächlich korrekt ist . Wenn Ihre Teamkollegen also nicht von 4 Tests überzeugt sind, brauchen Sie vielleicht mehr.
Die OTOH-Zeit zum Schreiben von Komponententests ist normalerweise eine knappe Ressource. So bemühen uns , die beste Art und Weise zu finden , die begrenzte Zeit zu verbringen Sie haben . Wenn Sie beispielsweise eine andere wichtige Methode mit 0% Abdeckung haben, ist es möglicherweise besser, ein paar Komponententests zu schreiben, um diese abzudecken, als zusätzliche Tests für diese Methode hinzuzufügen. Natürlich kommt es auch darauf an, wie fragil die Umsetzung der einzelnen ist. Wenn Sie in absehbarer Zeit viele Änderungen an dieser speziellen Methode vornehmen, kann dies eine zusätzliche Abdeckung durch Komponententests rechtfertigen. Möglicherweise befinden Sie sich innerhalb des Programms auf einem kritischen Pfad. Dies sind alles Faktoren, die nur Sie (Ihr Team) einschätzen können.
Ich persönlich würde normalerweise mit den 4 Tests, die Sie skizzieren, glücklich sein, das heißt:
plus vielleicht eins:
um sicherzustellen, dass der einzige Weg, einen Rückgabewert von zu erhalten, darin
true
besteht, alle drei Geschäftsregeln zu erfüllen. Aber wenn Ihre Teamkollegen darauf bestehen, dass kombinatorische Pfade abgedeckt werden, ist es möglicherweise billiger, diese zusätzlichen Tests hinzuzufügen, als das Argument viel länger fortzusetzen :-)quelle
Wenn Sie sicher sein möchten, benötigen Sie acht Einheitentests unter Verwendung der Bedingungen, die durch eine Wahrheitstabelle mit drei Variablen dargestellt werden ( http://teach.valdosta.edu/plmoch/MATH4161/Spring%202004/and_or_if_files/image006.gif ).
Sie können niemals sicher sein, dass die Geschäftslogik immer vorschreibt, dass die Überprüfungen in dieser Reihenfolge durchgeführt werden, und Sie möchten, dass der Test so wenig wie möglich über die tatsächliche Implementierung weiß.
quelle
Ja, in einer idealen Welt sollte es die vollständige Kombination geben.
Wenn Sie den Komponententest durchführen, sollten Sie wirklich versuchen, zu ignorieren, wie die Methode funktioniert. Geben Sie einfach die 3 Eingänge ein und überprüfen Sie, ob der Ausgang korrekt ist.
quelle
Staat ist böse. Die folgende Funktion benötigt keinen Komponententest, da sie keine Nebenwirkungen hat und gut verstanden ist, was sie tut und was nicht. Warum es testen? Traust du deinem eigenen Gehirn nicht ??? Statische Funktionen sind großartig!
quelle
a
,b
undc
. Sie können die Geschäftslogik beliebig verschieben, am Ende müssen Sie sie noch irgendwo testen.Ich weiß, dass diese Frage ziemlich alt ist. Aber ich möchte dem Problem eine andere Perspektive geben.
Erstens sollten Ihre Komponententests zwei Ziele haben:
what's the class' intention
und verstehenhow the class is doing its work
Um das Problem zusammenzufassen, wollen wir testen
complex if statement
, dass es für das gegebene Beispiel 2 ^ 3 Möglichkeiten gibt, das ist eine wichtige Menge von Tests, die wir schreiben können.what is doing the code
Wenn Sie jedoch der Meinung sind, dass Ihre Tests noch komplexer sind als die Implementierung, sollten Sie die Implementierung (je nach Fall mehr oder weniger) neu gestalten und nicht den Test selbst.
Für die komplexen if-Anweisungen könnten Sie beispielsweise über das Verantwortungsmuster der Kette nachdenken und jeden Handler folgendermaßen implementieren:
If some simple business rule apply, derive to the next handler
Wie einfach wäre es, anstelle einer komplexen Regel verschiedene einfache Regeln zu testen?
Ich hoffe es hilft,
quelle
Dies ist einer der Fälle, in denen etwas wie Quickcheck ( http://en.wikipedia.org/wiki/QuickCheck ) Ihr Freund sein wird. Anstatt alle N Fälle von Hand auszuschreiben, muss der Computer alle (oder zumindest eine große Anzahl) möglichen Testfälle generieren und validieren, dass alle ein vernünftiges Ergebnis liefern.
Wir programmieren Computer, um Ihren Lebensunterhalt hier zu verdienen. Warum programmieren wir nicht den Computer, um Ihre Testfälle für Sie zu generieren?
quelle
Sie können die Bedingungen in Schutzbedingungen umgestalten:
Ich denke nicht, dass dies die Anzahl der Fälle verringert, aber meiner Erfahrung nach ist es einfacher, sie auf diese Weise auszubrechen.
(Beachten Sie, dass ich ein großer Fan von "Single Point of Exit" bin, aber ich mache eine Ausnahme für Guard-Bedingungen. Es gibt jedoch auch andere Möglichkeiten, den Code zu strukturieren, sodass Sie keine separaten Rückgaben haben.)
quelle