Ich bin nicht sicher, wie TDD, die Methode, den folgenden Fall behandelt. Angenommen, ich möchte den Mergesort-Algorithmus in Python implementieren. Ich beginne mit dem Schreiben
assert mergesort([]) === []
und der Test schlägt fehl mit
NameError: Name 'mergesort' ist nicht definiert
Ich füge dann hinzu
def mergesort(a):
return []
und mein Test besteht. Als nächstes füge ich hinzu
assert mergesort[5] == 5
und mein Test schlägt fehl mit
AssertionError
womit ich zurechtkomme
def mergesort(a):
if not a:
return []
else:
return a
Als nächstes füge ich hinzu
assert mergesort([10, 30, 20]) == [10, 20, 30]
und ich muss jetzt versuchen, diesen Pass zu machen. Ich "kenne" den Mergesort-Algorithmus und schreibe:
def mergesort(a):
if not a:
return []
else:
left, right = a[:len(a)//2], a[len(a)//2:]
return merge(mergesort(left)), mergesort(right))
Und das scheitert mit
NameError: name 'merge' ist nicht definiert
Hier ist die Frage. Wie kann ich merge
mit TDD loslegen und mit der Implementierung beginnen ? Es scheint, als könnte ich nicht, weil ich diesen "hängenden" nicht erfüllten, fehlgeschlagenen Test für habe mergesort
, der nicht bestanden wird, bis er merge
beendet ist! Wenn dieser Test herumhängt, kann ich TDD nie wirklich durchführen, da ich während der Erstellung meiner TDD-Iterationen nicht "grün" bin merge
.
Es scheint, als ob ich bei den folgenden drei hässlichen Szenarien festgefahren bin und möchte wissen, (1) welches davon die TDD-Community bevorzugt oder (2) gibt es einen anderen Ansatz, den ich vermisse? Ich habe mir mehrere Walkthroughs zu Onkel Bob TDD angesehen und kann mich nicht erinnern, zuvor einen solchen Fall gesehen zu haben!
Hier sind die 3 Fälle:
- Implementieren Sie die Zusammenführung in einem anderen Verzeichnis mit einer anderen Testsuite.
- Machen Sie sich keine Sorgen, dass Sie beim Entwickeln der Hilfefunktion grün sind. Verfolgen Sie einfach manuell, welche Tests Sie wirklich bestehen möchten.
- Kommentieren Sie aus (GASP!) Oder löschen Sie die Zeilen in
mergesort
diesem Aufrufmerge
. Setzen Siemerge
sie dann wieder ein, nachdem Sie zur Arbeit gekommen sind.
Diese sehen alle albern aus (oder sehe ich das falsch?). Kennt jemand den bevorzugten Ansatz?
mergesort
, da es bereits ein sehr gut definierten Algorithmus wird dieser Erkennungsprozess nicht erforderlich ist , und es wird dann eine Frage der Zuordnung , was Sie bereits wissen , dass das Design auf eine Reihe von Unit - Tests zu sein. Vermutlich geht Ihr Top-Level-Test davon aus, dass Ihre getestete Methode eine unsortierte Sammlung akzeptiert und eine sortierte zurückgibt ...mergesort
. Wenn Sie nach dem "richtigen" Weg suchen, gibt es keinen anderen, als die Zuordnung desmergesort
Algorithmus zu einer Reihe von Komponententests zu präzisieren. dh sie sollten reflektieren, was einmergesort
eigentlich tut.mergesort
Design auf natürliche Weise aus dem Rot-Grün-Refaktor hervorgeht, geschieht dies nur, wenn Sie den Prozess auf der Grundlage Ihres vorhandenen Wissens über steuernmergesort
.merge
muss nur auf der "Refactoring" -Stufe erfunden werden. Wenn Sie sehen, dass diesemerge
Methode zum Bestehen einesmergesort
Tests eingeführt werden kann, lassen Sie Ihre Tests zunächst ohnemerge
Methode bestehen. Dann überarbeiten Sie Ihre Implementierung, indem Sie einemerge
Methode einführen .Antworten:
Hier sind einige alternative Möglichkeiten, um Ihre Optionen anzuzeigen. Aber zuerst die Regeln von TDD, von Onkel Bob mit Nachdruck von mir:
Eine Möglichkeit, Regel 3 zu lesen, besteht darin, dass Sie die
merge
Funktion zum Bestehen des Tests benötigen , damit Sie ihn implementieren können - jedoch nur in seiner grundlegendsten Form.Alternativ können Sie den Zusammenführungsvorgang zunächst in eine Zeile schreiben und ihn dann in eine Funktion umgestalten, nachdem der Test ausgeführt wurde.
Eine andere Interpretation ist, dass Sie Mergesort schreiben und wissen, dass Sie eine
merge
Operation benötigen (dh, es ist nicht YAGNI, was die "ausreichende" Regel zu verkürzen versucht). Daher sollten Sie mit Tests für die Zusammenführung begonnen haben und erst dann mit Tests für die Gesamtsorte fortfahren.quelle
merge
überraschend unübersichtlich ist, machte die Idee, es als separate Funktion auszuführen, mehr Sinn. Der Stil, es in seiner Grundform inline zu machen und es dann auf der Blue-Hat-Bühne auszublenden, scheint jedoch wirklich richtig und genau das zu sein, wonach ich gesucht habe.merge
Operation vor dem Sortieren vollständig zu testen (und die Operation separat zu testenpartition
). Ich denke, dass die behaupteten Vorteile des aufstrebenden Designs darin liegen, langsam auf ein bekanntes Ziel hinzuarbeiten. Im Falle von Mergesort denke ich nicht, dass das Ziel im Allgemeinen die Sortierung ist (weil dann die Blasensortierung enden wird). Sie kennen die grundlegenden Operationen und arbeiten auf diese Operationen hin. Die Sorte ist meist ein nachträglicher Einfall.merge
Funktionmergesort
und verspotten Sie ihr Verhalten. Dann gehen Sie zurück und implementierenmerge
Test zuerst. Die Delegierten sind fantastisch ™.