Dies sind die Regeln von Robert C. Martin für TDD :
- Sie dürfen keinen Produktionscode schreiben, es sei denn, es wird ein fehlerhafter Einheitentest bestanden.
- Sie dürfen nicht mehr von einem Komponententest schreiben, als zum Scheitern ausreicht. und Kompilierungsfehler sind Fehler.
- Sie dürfen nicht mehr Seriencode schreiben, als ausreicht, um den einen fehlgeschlagenen Komponententest zu bestehen.
Wenn ich einen Test schreibe, der sich lohnt, aber ohne Änderung des Produktionscodes besteht:
- Bedeutet das, dass ich etwas falsch gemacht habe?
- Sollte ich in Zukunft vermeiden, solche Tests zu schreiben, wenn es geholfen werden kann?
- Soll ich diesen Test dort lassen oder entfernen?
Hinweis: Ich habe versucht , diese Frage hier zu stellen: Kann ich mit einem bestandenen Komponententest beginnen? Aber ich konnte die Frage bis jetzt nicht gut genug formulieren.
testing
unit-testing
tdd
Daniel Kaplan
quelle
quelle
Antworten:
Es heißt, dass Sie keinen Produktionscode schreiben können, es sei denn, es muss ein fehlerhafter Komponententest bestanden werden. Die Absicht der Regel ist, zu sagen: "Wenn Sie Produktionscode bearbeiten müssen, stellen Sie sicher, dass Sie zuerst einen Test dafür schreiben oder ändern."
Manchmal schreiben wir Tests, um eine Theorie zu beweisen. Der Test besteht und das widerlegt unsere Theorie. Wir entfernen den Test dann nicht. Wir könnten jedoch (da wir wissen, dass wir die Quellcodeverwaltung unterstützen) den Produktionscode brechen, um sicherzustellen, dass wir verstehen, warum er bestanden hat, als wir es nicht erwartet hatten.
Wenn sich herausstellt, dass es sich um einen gültigen und korrekten Test handelt und kein vorhandener Test dupliziert wird, lassen Sie ihn dort.
quelle
Es bedeutet, dass entweder:
Die letztere Situation ist häufiger als Sie vielleicht denken. Nehmen wir an, Sie haben als ein völlig unspezifisches und triviales (aber dennoch veranschaulichendes) Beispiel den folgenden Komponententest geschrieben (Pseudocode, weil ich faul bin):
Denn alles, was Sie wirklich brauchen, ist das Ergebnis von 2 und 3 zusammen.
Ihre Implementierungsmethode wäre:
Angenommen, ich muss jetzt 4 und 6 addieren:
Ich muss meine Methode nicht umschreiben, da sie bereits den zweiten Fall abdeckt.
Nehmen wir an, ich habe herausgefunden, dass meine Add-Funktion wirklich eine Zahl mit einer Obergrenze von 100 zurückgeben muss. Ich kann eine neue Methode schreiben, die dies testet:
Und dieser Test wird jetzt fehlschlagen. Ich muss jetzt meine Funktion umschreiben
es passieren zu lassen.
Der gesunde Menschenverstand schreibt vor, dass wenn
Wenn der Test bestanden wird, wird die Methode nicht absichtlich zum Fehlschlagen gebracht, nur damit Sie einen fehlgeschlagenen Test durchführen und neuen Code schreiben können, um den Test zu bestehen.
quelle
add(2,3)
würden Sie buchstäblich 5 zurückgeben , um den Pass zu bestehen. Dann würden Sie den Test schreiben, füradd(4,6)
den Sie gezwungen wären, den Produktionscode zu schreiben, der ihn bestehen lässt, ohne gleichzeitig zu brechenadd(2,3)
. Sie würden am Ende mitreturn x + y
, aber Sie würden nicht mit ihm beginnen. In der Theorie. Natürlich mag Martin (oder vielleicht war es jemand anderes, an den ich mich nicht erinnere) solche Beispiele für die Erziehung, aber er erwartet nicht, dass Sie tatsächlich so trivialen Code schreiben.Ihr Test bestanden, aber Sie sind nicht falsch. Ich denke, es ist passiert, weil der Produktionscode nicht von Anfang an TDD ist.
Nehmen wir an, kanonisches (?) TDD. Es gibt keinen Seriencode, aber ein paar Testfälle (das schlägt natürlich immer fehl). Wir fügen Produktionscode hinzu, um zu übergeben. Dann hören Sie hier auf, um weitere Fehlertestfälle hinzuzufügen. Fügen Sie erneut Produktionscode hinzu, um zu übergeben.
Mit anderen Worten, Ihr Test kann eine Art Funktionstest sein, kein einfacher TDD-Komponententest. Diese sind immer ein wertvolles Gut für die Produktqualität.
Ich persönlich mag solche totalitären, unmenschlichen Regeln nicht.
quelle
Eigentlich ist das gleiche Thema gestern Abend in einem Dojo aufgetaucht.
Ich habe schnell recherchiert. Das habe ich mir ausgedacht:
Grundsätzlich ist dies nach den TDD-Regeln nicht explizit verboten. Möglicherweise sind einige zusätzliche Tests erforderlich, um zu beweisen, dass eine Funktion für eine verallgemeinerte Eingabe korrekt funktioniert. In diesem Fall bleibt die TDD-Praxis nur für kurze Zeit bestehen. Beachten Sie, dass ein kurzes Verlassen der TDD-Praxis nicht unbedingt gegen die TDD-Regeln verstößt, solange in der Zwischenzeit kein Seriencode hinzugefügt wurde.
Zusätzliche Tests können geschrieben werden, solange sie nicht redundant sind. Eine gute Vorgehensweise wäre, Partitionstests für Äquivalenzklassen durchzuführen. Das heißt, für jede Äquivalenzklasse werden die Kantenfälle und mindestens ein Innenfall geprüft.
Ein Problem, das bei diesem Ansatz auftreten kann, besteht darin, dass bei einem erneuten Bestehen der Tests nicht sichergestellt werden kann, dass keine falsch positiven Ergebnisse vorliegen. Dies bedeutet, dass möglicherweise Tests bestanden werden, weil die Tests nicht ordnungsgemäß implementiert wurden und der Produktionscode nicht ordnungsgemäß funktioniert. Um dies zu verhindern, sollte der Produktionscode leicht geändert werden, um den Test zu unterbrechen. Wenn der Test dadurch fehlschlägt, ist der Test höchstwahrscheinlich korrekt implementiert und der Produktionscode kann zurückgesetzt werden, um den Test erneut zu bestehen.
Wenn Sie nur striktes TDD üben möchten, schreiben Sie möglicherweise keine zusätzlichen Tests, die von Anfang an bestehen. Andererseits sollte man in einer Unternehmensentwicklungsumgebung die TDD-Praxis tatsächlich verlassen, wenn zusätzliche Tests nützlich erscheinen.
quelle
Ein Test, der ohne Änderung des Produktionscodes bestanden wird, ist von Natur aus nicht schlecht und wird oft benötigt, um eine zusätzliche Anforderung oder einen Grenzfall zu beschreiben. Solange Ihr Test "lohnenswert erscheint", wie Sie es sagen, behalten Sie ihn bei.
In Schwierigkeiten geraten Sie, wenn Sie einen bereits bestandenen Test als Ersatz für das tatsächliche Verständnis des Problembereichs schreiben.
Wir können uns zwei Extreme vorstellen: Ein Programmierer, der eine große Anzahl von Tests schreibt, "nur für den Fall", dass man einen Fehler entdeckt; und einen zweiten Programmierer, der den Problemraum sorgfältig analysiert, bevor er eine minimale Anzahl von Tests schreibt. Angenommen, beide versuchen, eine Absolutwertfunktion zu implementieren.
Der erste Programmierer schreibt:
Der zweite Programmierer schreibt:
Die Implementierung des ersten Programmierers kann zu folgenden Ergebnissen führen:
Die Implementierung des zweiten Programmierers kann zu folgenden Ergebnissen führen:
Alle Tests sind bestanden, aber der erste Programmierer hat nicht nur mehrere redundante Tests geschrieben (die den Entwicklungszyklus unnötig verlangsamen), sondern auch einen Grenzfall nicht getestet (
abs(0)
).Wenn Sie Tests schreiben, die ohne Änderung des Produktionscodes bestanden wurden, fragen Sie sich, ob Ihre Tests wirklich einen Mehrwert bringen oder ob Sie mehr Zeit für das Verständnis des Problemumfelds benötigen.
quelle
abs(n) = n*n
und bestanden hat.abs(-2)
. Moderation ist wie bei allem der Schlüssel.