Der Ansatz "Write Test + Refactor Till Pass" sieht unglaublich anti-engineering aus.
Sie scheinen ein Missverständnis über Refactoring und TDD zu haben.
Beim Code-Refactoring wird der Quellcode eines Computerprogramms geändert, ohne dass das externe Funktionsverhalten geändert wird, um einige der nicht funktionierenden Attribute der Software zu verbessern.
Daher können Sie Code erst dann umgestalten , wenn er erfolgreich ist.
Und bei TDD, insbesondere beim Unit-Testen (was ich als Kernverbesserung betrachte, da andere Tests für mich eher plausibel erscheinen), geht es nicht darum, eine Komponente neu zu entwerfen, bis sie funktioniert. Es geht darum, eine Komponente zu entwerfen und an der Implementierung zu arbeiten, bis die Komponente wie geplant funktioniert.
Es ist auch wichtig zu verstehen, dass es beim Unit- Testen um das Testen von Units geht . Aufgrund der Tendenz, immer viele Dinge von Grund auf neu zu schreiben, ist es wichtig, solche Einheiten zu testen. Ein Bauingenieur kennt bereits die Spezifikationen der von ihm verwendeten Einheiten (die verschiedenen Materialien) und kann erwarten, dass sie funktionieren. Dies sind zwei Dinge, die für Software-Ingenieure häufig nicht zutreffen, und es ist sehr pro-technisch, die Einheiten vor der Verwendung zu testen, da dabei getestete, hochwertige Komponenten verwendet werden.
Wenn ein Bauingenieur die Idee hätte, ein neues Fasergewebe für die Herstellung eines Daches zur Abdeckung eines Stadions zu verwenden, würde man von ihm erwarten, dass er es als Einheit testet, dh die erforderlichen Spezifikationen definiert (z. B. Gewicht, Durchlässigkeit, Stabilität usw.) und danach testen und verfeinern, bis es ihnen entspricht.
Deshalb funktioniert TDD. Denn wenn Sie Software aus getesteten Einheiten erstellen, ist die Wahrscheinlichkeit groß, dass sie funktioniert, wenn Sie sie zusammenstecken, und wenn dies nicht der Fall ist, können Sie davon ausgehen, dass das Problem in Ihrem Klebercode enthalten ist, vorausgesetzt, dass Ihre Tests eine gute Abdeckung aufweisen.
Bearbeiten:
Refactoring bedeutet: keine Änderung der Funktionalität. Beim Unit-Test muss sichergestellt werden, dass das Refactoring den Code nicht beschädigt. TDD soll also sicherstellen, dass Refactoring keine Nebenwirkungen hat.
Die Granularität ist kein Gegenstand der Perspektive, denn wie gesagt, Unit-Tests sind Testeinheiten und keine Systeme, bei denen die Granularität genau definiert ist.
TDD fördert gute Architektur. Es erfordert, dass Sie Spezifikationen für alle Ihre Einheiten definieren und implementieren, sodass Sie gezwungen sind, diese vor der Implementierung zu entwerfen, was ganz im Gegenteil zu Ihrer Vermutung ist. TDD schreibt die Erstellung von Einheiten vor, die einzeln getestet und somit vollständig entkoppelt werden können.
TDD bedeutet nicht, dass ich einen Softwaretest mit Spaghetti-Code mache und die Nudeln rühre, bis sie verstrichen sind.
Im Gegensatz zum Tiefbau entwickelt sich im Software-Engineering ein Projekt in der Regel ständig weiter. Im Tiefbau müssen Sie in Position A eine Brücke bauen, die x Tonnen tragen kann und breit genug für n Fahrzeuge pro Stunde ist.
In der Softwareentwicklung kann der Kunde grundsätzlich zu jedem Zeitpunkt (möglicherweise nach Fertigstellung) entscheiden, ob er eine Brücke mit Doppeldeck wünscht und ob er möchte, dass diese mit der nächsten Autobahn verbunden wird, und dass er möchte, dass sie eine Hebebrücke ist, weil sein Unternehmen vor kurzem begann Segelschiffe zu verwenden.
Software-Ingenieure haben die Aufgabe , das Design zu ändern. Nicht weil ihre Entwürfe fehlerhaft sind, sondern weil das der Modus operandi ist. Wenn die Software ausgereift ist, kann sie auf hoher Ebene neu gestaltet werden, ohne dass alle Komponenten auf niedriger Ebene neu geschrieben werden müssen.
Bei TDD geht es darum, Software mit individuell getesteten, stark entkoppelten Komponenten zu erstellen. Gut ausgeführt, wird es Ihnen helfen, schneller und sicherer auf geänderte Anforderungen zu reagieren als ohne.
TDD stellt zusätzliche Anforderungen an den Entwicklungsprozess, verbietet jedoch keine anderen Methoden zur Qualitätssicherung. Zugegeben, TDD bietet nicht die gleiche Sicherheit wie die formale Verifizierung. Andererseits ist die formale Verifizierung äußerst kostenintensiv und auf Systemebene nicht anwendbar. Und trotzdem könnten Sie beide kombinieren, wenn Sie wollten.
TDD umfasst auch andere Tests als Komponententests, die auf Systemebene durchgeführt werden. Ich finde diese einfach zu erklären, aber schwierig auszuführen und schwer zu messen. Auch sind sie durchaus plausibel. Obwohl ich ihre Notwendigkeit absolut sehe, schätze ich sie nicht wirklich als Ideen.
Am Ende löst kein Tool ein Problem. Werkzeuge erleichtern nur das Lösen eines Problems. Sie können sich fragen: Wie hilft mir ein Meißel bei großartiger Architektur? Wenn Sie gerade Wände bauen möchten, sind gerade Ziegel hilfreich. Und ja, selbstverständlich, wenn Sie einem Idioten dieses Werkzeug geben, wird er es wahrscheinlich irgendwann durch den Fuß schlagen, aber das ist nicht die Schuld des Meißels, so sehr es auch kein Fehler von TDD ist, dass es Anfängern falsche Sicherheit gibt. die schreiben keine guten tests.
Unterm Strich kann man also sagen, dass TDD viel besser funktioniert als kein TDD.