Angenommen, ich beginne mit der Entwicklung eines Rollenspiels mit Charakteren, die andere Charaktere und dergleichen angreifen.
Mit TDD mache ich einige Testfälle, um die Logik in der Character.receiveAttack(Int)
Methode zu testen . Etwas wie das:
@Test
fun healthIsReducedWhenCharacterIsAttacked() {
val c = Character(100) //arg is the health
c.receiveAttack(50) //arg is the suffered attack damage
assertThat(c.health, is(50));
}
Angenommen, ich habe 10 Methoden Testmethode receiveAttack
. Jetzt füge ich eine Methode hinzu Character.attack(Character)
(die receiveAttack
Methode aufruft ) und nach einigen TDD-Zyklen, die sie testen, treffe ich eine Entscheidung: Character.receiveAttack(Int)
sollte sein private
.
Was passiert mit den letzten 10 Testfällen? Soll ich sie löschen? Soll ich die Methode beibehalten public
(glaube ich nicht)?
Bei dieser Frage geht es nicht darum, wie private Methoden getestet werden, sondern wie mit ihnen nach einer Neugestaltung bei der Anwendung von TDD umgegangen wird
quelle
internal
oder in der entsprechenden Sprache markiert werden , um zu verhindern, dass sie angezeigt wird. In der Tat ist Kevin Clines Antwort diese Art von Ansatz.Antworten:
In TDD dienen die Tests als ausführbare Dokumentation Ihres Designs. Ihr Design hat sich geändert, also muss natürlich auch Ihre Dokumentation!
Beachten Sie, dass die
attack
Methode in TDD nur als Ergebnis eines fehlgeschlagenen Testdurchlaufs hätte angezeigt werden können. Was bedeutet,attack
wird von einem anderen Test getestet. Das bedeutet, dass indirektreceiveAttack
durchattack
die Tests abgedeckt wird . Im Idealfall sollte jede ÄnderungreceiveAttack
mindestens einen derattack
Tests unterbrechen.Und wenn nicht, dann gibt es Funktionen
receiveAttack
, die nicht mehr benötigt werden und nicht mehr existieren sollten!Da dies
receiveAttack
bereits getestet wurdeattack
, spielt es keine Rolle, ob Sie Ihre Tests behalten oder nicht. Wenn Ihr Test - Framework macht es einfach , private Methoden zu testen, und wenn Sie sich entscheiden , private Methoden zu testen, dann können Sie sie halten. Sie können sie jedoch auch löschen, ohne die Testabdeckung und das Vertrauen zu verlieren.quelle
Wenn die Methode so komplex ist, dass sie getestet werden muss, sollte sie in einer Klasse öffentlich sein. So refactor Sie aus:
zu:
Verschieben Sie den aktuellen Test für X.complexity nach ComplexityTest. Dann schreiben Sie X. Etwas, indem Sie sich über die Komplexität lustig machen.
Nach meiner Erfahrung bringt die Umgestaltung auf kleinere Klassen und kürzere Methoden enorme Vorteile. Sie sind leichter zu verstehen, leichter zu testen und werden am Ende mehr als erwartet wiederverwendet.
quelle
this.health = this.health - attackDamage
). Vielleicht ist es für diesen Moment eine überentwickelte Lösung, es in eine andere Klasse zu extrahieren.Beachten Sie hierbei, dass Sie eine Methode aus der API entfernen müssen . Die Höflichkeit der Abwärtskompatibilität würde vorschlagen
Die Tests werden entfernt bzw. ersetzt, wenn Ihre API die Methode nicht mehr unterstützt. Zu diesem Zeitpunkt ist die private Methode ein Implementierungsdetail, das Sie überarbeiten können sollten.
An diesem Punkt befinden Sie sich wieder in der Standardfrage, ob Ihre Testsuite direkt auf Implementierungen zugreifen soll, statt nur über die öffentliche API zu interagieren. Eine private Methode sollte ersetzt werden können, ohne dass die Testsuite stört . Daher würde ich davon ausgehen, dass das Testpaar aufhört - entweder in den Ruhestand zu gehen oder mit der Implementierung auf eine separat testbare Komponente umzusteigen.
quelle