Während ich alle für Unit-Tests bin, frage ich mich manchmal, ob diese Form der ersten Testentwicklung wirklich von Vorteil ist ...
Kleine, triviale Tests wie dieser können der "Kanarienvogel im Kohlenbergwerk" für Ihre Codebasis sein und auf Gefahren aufmerksam machen, bevor es zu spät ist. Die trivialen Tests sind nützlich, um auf dem Laufenden zu bleiben, da sie Ihnen helfen, die richtigen Interaktionen zu erzielen.
Denken Sie beispielsweise an einen einfachen Test, mit dem untersucht wird, wie eine API verwendet wird, mit der Sie nicht vertraut sind. Wenn dieser Test für das, was Sie in dem Code tun, der die API "echt" verwendet, relevant ist, ist es nützlich, diesen Test beizubehalten. Wenn die API eine neue Version veröffentlicht und Sie ein Upgrade durchführen müssen. Sie haben jetzt Ihre Annahmen darüber, wie sich die API voraussichtlich in einem ausführbaren Format verhält, mit dem Sie Regressionen abfangen können.
... [I] In einem realen Prozess befinden sich 3-4 Ebenen über Ihrem Code (Geschäftsanforderung, Anforderungsdokument, Architekturdokument), in denen die tatsächlich definierte Geschäftsregel (Rabattpreis ist Preis - Rabatt) möglicherweise falsch definiert ist. In diesem Fall bedeutet Ihnen Ihr Komponententest nichts.
Wenn Sie jahrelang programmiert haben, ohne Tests zu schreiben, ist Ihnen möglicherweise nicht sofort klar, dass es einen Wert gibt. Wenn Sie jedoch der Meinung sind, dass die beste Art zu arbeiten "früh, häufig veröffentlichen" oder "agil" ist, da Sie die Möglichkeit haben möchten, schnell / kontinuierlich bereitzustellen, dann bedeutet Ihr Test definitiv etwas. Die einzige Möglichkeit, dies zu tun, besteht darin, jede Änderung, die Sie am Code vornehmen, mit einem Test zu legitimieren. Egal wie klein der Test ist, sobald Sie eine grüne Testsuite haben, können Sie sie theoretisch bereitstellen. Siehe auch "kontinuierliche Produktion" und "Perpetual Beta".
Sie müssen auch nicht "zuerst testen", um dieser Einstellung zu entsprechen, aber das ist im Allgemeinen der effizienteste Weg, um dorthin zu gelangen. Wenn Sie TDD durchführen, sperren Sie sich in einen kleinen Rot-Grün-Refaktor-Zyklus von zwei bis drei Minuten ein. Zu keinem Zeitpunkt können Sie anhalten und gehen und haben ein komplettes Durcheinander in Ihren Händen, dessen Debuggen und Zusammensetzen eine Stunde dauern wird.
Darüber hinaus ist Ihr Unit-Test ein weiterer Fehlerpunkt ...
Ein erfolgreicher Test zeigt einen Fehler im System. Ein fehlgeschlagener Test macht Sie auf einen Fehler in der Logik des Tests oder in der Logik Ihres Systems aufmerksam. Das Ziel Ihrer Tests ist es, Ihren Code zu brechen oder zu beweisen, dass ein Szenario funktioniert.
Wenn Sie Tests nach dem Code schreiben , laufen Sie Gefahr, einen Test zu schreiben, der "schlecht" ist, denn um zu sehen, dass Ihr Test wirklich funktioniert, müssen Sie sehen, dass er sowohl fehlerhaft als auch funktioniert. Wenn Sie Tests nach dem Code schreiben, bedeutet dies, dass Sie "die Falle stellen" und einen Fehler in den Code einfügen müssen, damit der Test fehlschlägt. Die meisten Entwickler sind sich darüber nicht nur unwohl, sondern würden auch argumentieren, dass dies Zeitverschwendung ist.
Was gewinnen wir hier?
Es ist definitiv ein Vorteil, Dinge auf diese Weise zu tun. Michael Feathers definiert "Legacy-Code" als "ungetesteten Code". Wenn Sie diesen Ansatz wählen, legitimieren Sie jede Änderung, die Sie an Ihrer Codebasis vornehmen. Es ist strenger als keine Tests zu verwenden, aber wenn es darum geht, eine große Codebasis aufrechtzuerhalten, zahlt es sich aus.
Apropos Federn, es gibt zwei großartige Ressourcen, die Sie in diesem Zusammenhang prüfen sollten:
Beide erklären, wie diese Art von Praktiken und Disziplinen in Projekte umgesetzt werden können, die nicht "Greenfield" sind. Sie bieten Techniken zum Schreiben von Tests für eng gekoppelte Komponenten, fest verdrahtete Abhängigkeiten und Dinge, über die Sie nicht unbedingt die Kontrolle haben. Es geht darum, "Nähte" zu finden und diese zu testen.
[I] Wenn der Rabattpreis falsch ist, wird das Testteam immer noch das Problem finden. Wie haben Unit-Tests Arbeit gespart?
Gewohnheiten wie diese sind wie eine Investition. Die Rückgabe erfolgt nicht sofort. Sie bauen sich im Laufe der Zeit auf. Die Alternative zum Nicht-Testen besteht im Wesentlichen darin, die Schuld zu übernehmen, keine Regressionen abfangen zu können, Code ohne Angst vor Integrationsfehlern einzuführen oder Entwurfsentscheidungen zu treffen. Das Schöne ist, dass Sie jede Änderung in Ihrer Codebasis legitimieren.
Was vermisse ich hier? Bitte bringen Sie mir bei, TDD zu lieben, da es mir bisher schwer fällt, es als nützlich zu akzeptieren. Ich will auch, weil ich progressiv bleiben will, aber es macht für mich einfach keinen Sinn.
Ich betrachte es als berufliche Verantwortung. Es ist ein Ideal, um danach zu streben. Aber es ist sehr schwer zu folgen und langweilig. Wenn Sie sich darum kümmern und der Meinung sind, dass Sie keinen Code produzieren sollten, der nicht getestet wurde, können Sie die Willenskraft finden, um gute Testgewohnheiten zu erlernen. Eine Sache, die ich jetzt viel mache (wie andere auch), ist, mir eine Stunde Zeit zu geben, um Code ohne Tests zu schreiben und dann die Disziplin zu haben, ihn wegzuwerfen. Das mag verschwenderisch erscheinen, ist es aber nicht wirklich. Es ist nicht so, dass Übung physische Materialien eines Unternehmens kostet. Es hat mir geholfen, das Problem zu verstehen und Code so zu schreiben, dass er sowohl von höherer Qualität als auch testbar ist.
Mein Rat wäre letztendlich, wenn Sie wirklich nicht den Wunsch haben, gut darin zu sein, dann tun Sie es überhaupt nicht. Schlechte Tests, die nicht gewartet werden, nicht gut funktionieren usw. können schlimmer sein als keine Tests. Es ist schwer, alleine zu lernen, und Sie werden es wahrscheinlich nicht lieben, aber es wird so gut wie unmöglich sein, es zu lernen, wenn Sie nicht den Wunsch haben, es zu tun, oder nicht genug Wert darin sehen können garantieren die Zeitinvestition.
Ein paar Leute erwähnen immer wieder, dass Tests helfen, die Spezifikation durchzusetzen. Ich habe die Erfahrung gemacht, dass die Spezifikation auch meistens falsch war ...
Auf der Tastatur eines Entwicklers trifft der Gummi auf die Straße. Wenn die Spezifikation falsch ist und Sie die Flagge nicht darauf hissen, werden Sie höchstwahrscheinlich dafür verantwortlich gemacht. Oder zumindest Ihr Code wird. Die Disziplin und Genauigkeit, die mit dem Testen verbunden ist, ist schwer einzuhalten. Es ist überhaupt nicht einfach. Es braucht Übung, viel Lernen und viele Fehler. Aber irgendwann zahlt es sich aus. Bei einem schnelllebigen, sich schnell ändernden Projekt ist dies die einzige Möglichkeit, nachts zu schlafen, unabhängig davon, ob es Sie verlangsamt.
Eine andere Sache, über die man hier nachdenken sollte, ist, dass Techniken, die im Wesentlichen mit dem Testen identisch sind, in der Vergangenheit nachweislich funktionieren: "Reinraum" und "Design by Contract" erzeugen beide tendenziell die gleichen Arten von "Meta" -Code-Konstrukten, die Tests tun und erzwingen diese an verschiedenen Punkten. Bei keiner dieser Techniken handelt es sich um Silberkugeln, und die Genauigkeit kostet Sie letztendlich den Umfang der Funktionen, die Sie in Bezug auf die Markteinführungszeit bereitstellen können. Aber darum geht es nicht. Es geht darum, das zu erhalten, was Sie liefern. Und das ist für die meisten Projekte sehr wichtig.