Ich versuche TDD für meine Programmierpraxis zu verwenden. Ich würde gerne fragen, ob ich mit Daten testen sollte, die nicht in einer Funktion passieren sollten, ABER diese Daten können möglicherweise Ihr Programm beschädigen.
Hier ist ein einfaches Beispiel, um zu illustrieren, was ich frage:
eine ROBOT-Funktion mit einem INT-Parameter. In dieser Funktion weiß ich, dass der gültige Bereich nur 0-100 betragen würde. Wenn -1, 101 verwendet wird, wird die Funktion unterbrochen.
%Vor%Also habe ich einige automatisierte Testfälle für diese Funktion gewählt ...
%Vor%Aber sollte ich Testfälle mit Eingabeargument -1 oder 101 für diese ROBOT-Funktion schreiben WENN ich das in meiner anderen Funktion, die Aufruffunktion ROBOT ???
, bewachen würde %Vor%Ich weiß nicht, ob es notwendig ist, weil ich denke, dass es Redundanz ist, um -1 und 101 zu testen. Und wenn es wirklich notwendig ist, alle Fälle abzudecken, muss ich mehr Code schreiben, um -1 und 101 zu schützen.
Also schreiben Sie in der üblichen Praxis von TDD Testfall auf -1 und 101 ???
Kurz gesagt, wenn es kaputt gehen kann, sollten Sie es testen. Überprüfen Sie die Daten auch zum frühestmöglichen Zeitpunkt.
Die Antwort hängt davon ab, ob Sie die an Robot übergebenen Eingaben steuern. Wenn Robot eine interne Klasse (C #) ist; Werte fließen nur vom RobotClientX ein, der ein öffentlicher Typ ist. Dann legte ich die Wächter-Checks in RobotClientX, schreibe Tests dafür. Ich würde keine Tests für Robot schreiben, weil ungültige Werte dazwischen nicht auftreten können. z.B. Wenn ich meine Validierungen so in die GUI setze, dass alle ungültigen Werte an der Quelle herausgefiltert werden, dann überprüfe ich nicht auf ungültige Werte in allen Klassen unterhalb der GUI (Es sei denn, ich habe auch eine öffentliche API veröffentlicht, die die GUI umgeht) .
Andererseits, wenn Roboter öffentlich sichtbar ist, d. h. jeder Roboter mit jedem beliebigen Wert aufrufen kann, dann brauche ich Tests, die sein Verhalten bei bestimmten Arten von Eingaben dokumentieren. Ungültig ist einer von ihnen. z.B. Wenn Sie einen Wert außerhalb des Bereichs übergeben, wird eine ArgumentException ausgelöst.
Ja, Sie sollten diese ungültigen Eingaben testen. ABER, wenn Ihre Sprache Zugriffsmodifizierer hat und ROBOT()
privat ist, sollten Sie es nicht testen; Sie sollten nur öffentliche Funktionen / Methoden testen.
Die Funktionsprüfung wird Grenzwertanalyse genannt.
Wenn Ihr Bereich 0-100 ist, sind Ihre Grenzwerte 0 und 100. Sie sollten testen, mindestens :
In diesem Fall:
-1,0,1,
99,100,101
Sie nehmen an, dass alles unter -1 bis -infinity sich gleich verhält, alles zwischen 1-99 verhält sich genauso und alles über 101 verhält sich genauso. Dies wird Äquivalenzpartitionierung genannt. Die Bereiche außerhalb und zwischen den Randwerten werden als Partitionen bezeichnet und Sie gehen davon aus, dass sie ein gleichwertiges Verhalten aufweisen.
Sie sollten immer die Verwendung von -1 als Testfall in Betracht ziehen, um sicherzustellen, dass bei negativen Zahlen und einer Textzeichenfolge, wenn der Parameter nicht stark typisiert ist, nichts Lustiges passiert.
Wenn das erwartete Ergebnis darin besteht, dass eine Ausnahme mit ungültigen Eingabewerten ausgelöst wird, ist ein Test geeignet, bei dem die Ausnahmen ordnungsgemäß ausgelöst werden.
Bearbeiten:
Wie ich in meinem Kommentar unten bemerkt habe, sollten Sie eine Ausnahme auslösen, wenn diese Fälle Ihre Anwendung zerstören. Wenn es wirklich logisch unmöglich ist, dass diese Fälle auftreten, dann würde ich nein sagen, Sie brauchen keine Ausnahme zu werfen, und Sie brauchen keine Testfälle, um sie abzudecken.
Beachten Sie, dass, wenn Ihr System gut komponiert ist und diese Funktion eine Komponente ist, die Tatsache, dass es logisch jetzt unmöglich ist, nicht bedeutet, dass es logisch immer unmöglich ist. Es kann anders auf der Straße verwendet werden.
Sie haben gesagt, dass Ihre Methode eine Ausnahme auslösen wird, wenn das Argument nicht gültig ist.
Also, ja, sollten Sie, weil Sie testen sollten, dass die Ausnahme ausgelöst wird.
Die Programmierung nach Vertrag Art des Designs und der Implementierung lenkt die Aufmerksamkeit auf die Tatsache, dass eine einzelne Funktion (Methode) nur für einige Dinge verantwortlich sein sollte, nicht für alles. Die anderen Funktionen, die es anruft (delegates to) und die es aufrufen, haben ebenfalls Verantwortlichkeiten. Diese Aufteilung der Verantwortlichkeiten ist der Kern der Aufteilung der Aufgabe der Programmierung in kleinere Aufgaben, die getrennt durchgeführt werden können. Der Vertrag Teil der vertraglichen Programmierung besteht darin, dass die Spezifikation einer Funktion angibt, was eine Funktion tun muss genau dann, wenn der Aufrufer der Funktion die Verantwortlichkeiten des Aufrufers erfüllt durch diese Spezifikation. Die Anforderung, dass die Eingabe-Ganzzahl innerhalb des Bereichs [0,100] liegt, ist diese Art von Anforderung.
Nun sollten Komponententests die Implementierungsdetails nicht testen. Sie sollten testen, dass die Funktion ihrer Spezifikation entspricht. Dies ermöglicht eine Änderung der Implementierung, ohne dass die Tests brechen. Es macht Refactoring möglich.
Kombinieren Sie diese beiden Ideen, wie können wir einen Test für eine Funktion schreiben, die eine bestimmte ungültige Eingabe erhält? Wir sollten prüfen, ob sich die Funktion _gemäß der Spezifikation * verhält. Aber die Spezifikation sagt nicht, was die Funktion in diesem Fall tun muss. So können wir nach dem ungültigen Funktionsaufruf keine Überprüfungen des Programmzustandes schreiben; Das Verhalten ist undefiniert . Also können wir überhaupt keinen solchen Test schreiben.
Meine Antwort ist, dass, nein, Sie wollen keine Ausnahmen, Sie möchten nicht, dass ROBOT()
auf Eingaben außerhalb des Bereichs überprüft. Die Clients sollten sich so gut benehmen, dass sie keine Müllwerte übergeben.
Vielleicht möchten Sie dies dokumentieren - Sagen Sie einfach, dass Clients auf die übergebenen Werte achten müssen.
Abgesehen davon, wo wirst du ungültige Werte bekommen? Nun, Benutzereingaben oder durch Umwandlung von Strings in Zahlen. In diesen Fällen sollten jedoch die Konvertierungsroutinen die Prüfungen durchführen und Rückmeldungen darüber geben, ob die Werte gültig sind oder nicht. Die Werte sollten garantiert gültig sein, lange bevor sie irgendwo in der Nähe von ROBOT()
ankommen!
Tags und Links unit-testing testing tdd