Ursprünglich stammte TDD aus der agilen Bewegung, in der Tests im Voraus geschrieben wurden, um sicherzustellen, dass das, was Sie codiert haben, angesichts der Spezifikation, die jetzt im Testcode genau definiert ist, korrekt bleibt. Es schien auch ein sehr wichtiger Aspekt des Refactorings zu sein, da Sie sich beim Ändern Ihres Codes auf die Tests verlassen konnten, um zu beweisen, dass Sie das Verhalten des Codes nicht geändert hatten.
Dann kamen die Tools-Leute und dachten, sie wüssten Informationen über Ihren Code und könnten dann Teststubs generieren, die Sie beim Schreiben Ihrer Komponententests unterstützen, und ich denke, hier ist alles schief gelaufen.
Die Teststubs werden von einem Computer generiert, der keine Ahnung hat, was Sie gerade tun. Er erzeugt nur gedankenlos einen Stub für jede Methode, da er dazu aufgefordert wird. Dies bedeutet, dass Sie für jede Methode einen Testfall haben, unabhängig von der Komplexität dieser Methode oder davon, ob sie für isolierte Tests geeignet ist.
Dies geschieht beim Testen am falschen Ende der TDD-Methodik. In TDD sollten Sie herausfinden, was der Code tun soll, und dann Code erstellen, der dies erreicht. Dies ist insofern selbsterfüllend, als Sie am Ende Tests schreiben, die beweisen, dass der Code das tut, was der Code tut, und nicht das, was er tun soll. In Kombination mit der automatischen Generierung methodenbasierter Teststubs verschwenden Sie so ziemlich Ihre Zeit damit, jeden winzigen Aspekt Ihres Codes zu beweisen, der sich so leicht als falsch erweisen kann, wenn alle kleinen Teile zusammengefügt werden.
Als Fowler das Testen in seinem Buch beschrieb, bezog er sich darauf, jede Klasse mit ihrer eigenen Hauptmethode zu testen. Er hat dies verbessert, aber das Konzept ist immer noch dasselbe - Sie testen die gesamte Klasse, damit es als Ganzes funktioniert. Alle Ihre Tests werden gebündelt, um die Interaktion all dieser Methoden zu beweisen, damit die Klasse mit definierten Erwartungen wiederverwendet werden kann.
Ich denke, die Test-Toolkits haben uns einen schlechten Dienst erwiesen und uns auf den Weg gebracht zu denken, dass das Toolkit die einzige Möglichkeit ist, Dinge zu tun, wenn Sie wirklich mehr selbst überlegen müssen, um das beste Ergebnis aus Ihrem Code zu erzielen. Das blinde Einfügen von Testcode in Teststubs für winzige Teile bedeutet nur, dass Sie Ihre Arbeit ohnehin in einem Integrationstest wiederholen müssen (und wenn Sie dies tun möchten, können Sie die jetzt redundante Unit-Testphase vollständig überspringen). Dies bedeutet auch, dass die Benutzer viel Zeit damit verschwenden, eine 100% ige Testabdeckung zu erreichen, und viel Zeit damit, große Mengen an verspottetem Code und Daten zu erstellen, die besser dafür aufgewendet worden wären, den Code für Integrationstests einfacher zu machen (dh wenn Sie so viel haben Datenabhängigkeiten, Unit-Test ist möglicherweise nicht die beste Option)
Schließlich zeigt die Fragilität methodischer Unit-Tests nur das Problem. Refactoring wurde für Unit-Tests entwickelt. Wenn Ihre Tests ständig unterbrochen werden, weil Sie Refactoring durchführen, ist bei der gesamten Vorgehensweise ein schwerwiegender Fehler aufgetreten. Refactoring erstellt und löscht gerne Methoden, daher ist der auf Methoden basierende blinde Testansatz offensichtlich nicht das, was ursprünglich beabsichtigt war.
Ich habe keine Zweifel, dass für viele Methoden Tests geschrieben werden. Alle öffentlichen Methoden einer Klasse sollten getestet werden, aber Sie können nicht von dem Konzept abweichen, sie als Teil eines einzelnen Testfalls zusammen zu testen. Wenn ich zum Beispiel eine Set- und eine Get-Methode habe, kann ich Tests schreiben, die die Daten einfügen und überprüfen, ob die internen Mitglieder in Ordnung sind, oder ich kann jede verwenden, um einige Daten einzufügen und sie dann wieder herauszuholen, um zu sehen, ob sie vorhanden sind immer noch das gleiche und nicht verstümmelt. Dies testet die Klasse, nicht jede Methode für sich. Wenn der Setter auf eine private Hilfsmethode angewiesen ist, ist das in Ordnung. Sie müssen die private Methode nicht verspotten, um sicherzustellen, dass der Setter funktioniert, und nicht, wenn Sie die gesamte Klasse testen.
Ich denke, die Religion befasst sich mit diesem Thema, daher sehen Sie das Schisma in der heutigen "verhaltensgesteuerten" und "testgesteuerten" Entwicklung - das ursprüngliche Konzept des Unit-Tests war für die verhaltensgesteuerte Entwicklung.