Ich habe lange Zeit Code im TDD-Stil entworfen und entwickelt. Was mich an TDD stört, ist das Schreiben von Tests für Code, der keine Geschäftslogik oder interessantes Verhalten enthält. Ich weiß, dass TDD mehr eine Designaktivität als ein Test ist, aber manchmal halte ich es für nutzlos, Tests in diesen Szenarien zu schreiben.
Zum Beispiel habe ich ein einfaches Szenario wie "Wenn der Benutzer auf die Schaltfläche" Überprüfen "klickt, sollte die Gültigkeit der Datei überprüft werden" . Für dieses Szenario schreibe ich normalerweise Tests für die Presenter / Controller-Klasse wie die folgende.
@Test
public void when_user_clicks_check_it_should_check_selected_file_validity(){
MediaService service =mock(MediaService);
View view =mock(View);
when(view.getSelectedFile).thenReturns("c:\\Dir\\file.avi");
MediaController controller =new MediaController(service,view);
controller.check();
verify(service).check("c:\\Dir\\file.avi");
}
Wie Sie sehen, gibt es keine Entwurfsentscheidung oder interessanten Code zur Überprüfung des Verhaltens. Ich teste Werte aus der an MediaService übergebenen Ansicht. Normalerweise schreibe ich, aber ich mag solche Tests nicht. Was tun Sie in diesen Situationen? Schreibst du die ganze Zeit Tests?
UPDATE:
Ich habe den Testnamen und den Code nach Beschwerden geändert. Einige Benutzer sagten, dass Sie Tests für solche trivialen Fälle schreiben sollten, damit in Zukunft jemand interessantes Verhalten hinzufügen könnte. Aber was ist mit "Code für heute, Design für morgen". ? Wenn jemand, einschließlich ich, in Zukunft interessanteren Code hinzufügt, kann der Test dafür erstellt werden. Warum sollte ich es jetzt für die trivialen Fälle tun?
quelle
Antworten:
Ich strebe keine 100% ige Codeabdeckung an. Und ich schreibe normalerweise keine Tests von Methoden, die offensichtlich keine Geschäftslogik und / oder mehr als ein paar Codezeilen enthalten. Aber ich schreibe immer noch Unit-Tests (mit TDD) von Methoden, die nicht so komplex erscheinen. Dies liegt hauptsächlich daran, dass ich den Komponententest bereits gerne habe, wenn ich Monate oder sogar Jahre später auf diesen Code zurückkomme, und ihn komplexer gestalten möchte. Es ist immer einfacher, vorhandene Tests zu erweitern, als alles von Grund auf neu zu erstellen. Wie Noufal sagte, ist es subjektiv. Mein Rat ist, die Tests zu schreiben, wenn Sie der Meinung sind, dass die Methode etwas komplex ist oder das Potenzial hat, komplexer zu werden.
quelle
Dies ist heute die zweite TDD-Frage, die Ärger über die Anzahl der zu schreibenden Tests vermittelt.
"Testen Sie es nur, wenn Sie möchten, dass es funktioniert."
Ich bin mir nicht sicher, ob ich den Test in der Frage verstehe.
Überprüfen Sie, ob Controller.Check () an den Dienst delegiert (Abhängigkeit), wobei das Argument der ausgewählte Dateiwert aus der Ansicht ist? Wenn ja, ist dies ein guter Test. Sie können den Controller ohne die eigentliche Service-Implementierung testen. (interaktionsbasierte Mikrotests).
Update: Jetzt, da mir klar ist, was Sie testen möchten, würde ich wahrscheinlich Code verschieben und einige Dinge umbenennen, sodass "Test Media Controller delegiert die Prüfung ausgewählter Dateien an den Mediendienst delegiert" angezeigt wird. - Dies ist eine gültige Spezifikation für die Steuerung.
quelle
Ich würde so einen Test nicht schreiben (oder zumindest würde ich ihn nicht so nennen). Stattdessen würde ich einen Test für die Funktion schreiben, für die dieser Aufruf erforderlich ist.
check()
Wenn diese Überprüfung oder eine gleichwertige Aktion nicht durchgeführt wird, funktioniert die übergeordnete Funktion nicht. Warum muss Ihr Code diecheck()
Methode aufrufen ?Im Allgemeinen versuche ich, die Tests von den Implementierungsdetails entkoppelt zu halten, sodass zumindest der Name des Tests nur über die vom Objekt bereitgestellten externen Funktionen spricht. Implementierungsdetails wie Objekte und Methoden werden im Testnamen nicht erwähnt.
Dies erleichtert das Refactoring (es sollte nicht erforderlich sein, Tests zu ändern, wenn Sie die Implementierung ändern), und es erleichtert auch, herauszufinden, ob ein Test veraltet ist (die angegebene Funktion wird nicht mehr benötigt). . Dies erleichtert auch das Erkennen von unnötigem / totem Code, da Low-Level-Boilerplate (wie Getter und Setter) nur hinzugefügt / aufbewahrt werden, wenn sie für übergeordnete Funktionen erforderlich sind.
quelle
Das ist subjektiv. Ich mache nicht immer TDD, aber wenn ich das mache, versuche ich, die Codeabdeckung als meine Metrik dafür beizubehalten, ob meine Tests umfassend sind oder nicht. Manchmal werde ich faul und überspringe einfach Teile, die mir "offensichtlich" erscheinen. Manchmal verletze ich den Rot-, Grün- und Refaktor-Zyklus und schreibe mehr Code als nötig, aber im Laufe der Zeit bin ich in einen Rhythmus geraten, mit dem ich mich nicht wohl fühle.
quelle
Interaktionen zwischen Klassen wie den oben genannten und dem einfacheren Original, für das ich einen Test schreiben würde. Interaktionen können im Laufe der Zeit komplexer werden, daher ist es eine gute Sache, die Grundlagen zu schaffen.
quelle
Sie gehen davon aus, dass in Zukunft jemand weiß, dass dieses UI-Element vorhanden ist und wie es im Backend aufgerufen wird.
Mein aktuelles Projekt hat über 30 Entwickler in sechs verschiedenen Teams innerhalb derselben Codebasis. Triviale UI-Ergänzungen verschwinden ständig im Nebel. Niemand wird später zurückgehen und einen Testfall hinzufügen, weil sich niemand daran erinnern wird, dass er da ist, und wenn er bricht, lautet die Forderung: "Warum haben sie keinen Test geschrieben? Es wäre so einfach gewesen!"
quelle
Wie gewöhnlich...
Es hängt davon ab, ob
Es ist schwierig, die Nützlichkeit dieses speziellen Tests in einem TDD-Kontext zu erkennen, da wir die Geschichte nicht kennen.
Wenn die Geschichte lautet Als [Medienbenutzer] möchte ich [die Gültigkeit der Medien überprüfen können], damit [ich weiß, wenn eine Datei nicht verfügbar ist]
dann das Szenario Gegeben [eine Schaltfläche zum Überprüfen des Mediums] Wenn [der Benutzer auf die Schaltfläche klickt], dann [wird die Gültigkeit der Datei überprüft]
macht Sinn. Es ist trivial, aber es macht Sinn.
Wenn die übergreifende Geschichte größer ist, ist die Szenariodefinition möglicherweise zu eng.
Merken:
TDD! = Unit Testing
TDD testet Funktionen . Wenn es sich um eine Funktion handelt, verdient sie einen Test, um sie zu überprüfen.
quelle