Sollte ich Tests schreiben, wenn ich die Korrektheit des Codes nachweisen kann?

8

Die Leute sagen, dass "über TDD zu sprechen kaum funktioniert, wenn Sie jemanden von TDD überzeugen wollen, zeigen Sie ihm Ergebnisse". Ohne TDD bekomme ich jedoch bereits großartige Ergebnisse. Wenn ich zeige, dass Menschen, die TDD verwenden, keine guten Ergebnisse erzielen, kann ich nicht überzeugen. Ich möchte sehen, dass Menschen, die sowohl TDD als auch Nicht-TDD schreiben, mit TDD bessere Ergebnisse erzielen.

Trotz alledem bin ich daran interessiert, TDD auszuprobieren. Ich bin jedoch nicht davon überzeugt, dass ich daraus etwas gewinnen werde. Wenn es sich als nützlich erweist, werde ich versuchen, es an den Rest meines Teams weiterzuleiten.

Meine Hauptfrage lautet: Würde TDD einen Zweck für Code erfüllen, wenn ich die Korrektheit des Codes bereits nachweisen kann?

Offensichtlich ist keiner eine Silberkugel. Ihr Beweis ist möglicherweise falsch, weil Sie ein Detail übersehen haben und Ihr Test möglicherweise keinen Fehler erkennt, auf den Sie nicht getestet haben. Am Ende sind wir Menschen, niemand kann für immer 100% fehlerfreien Code erstellen. Wir können uns nur bemühen, so nah wie möglich zu kommen.

Würde TDD jedoch tatsächlich Zeit für Code sparen, dessen Richtigkeit nachgewiesen wurde? dh Code, bei dem in der Zustandsmaschine, auf der der Code ausgeführt wird, alle gültigen möglichen Zustände und ihre Bereiche vom Entwickler erkannt werden, alle berücksichtigt werden und der Code in einer Fehlerprüfung im Whitelist-Stil entworfen wird, an die jede Ausnahme übergeben wird ein oberer Handler, um sicherzustellen, dass keine unerwarteten Lecks auftreten -> ohne dass dem Client eine (innerhalb des Grundes) relevante Nachricht angezeigt und Protokollbenachrichtigungen an einen Administrator gesendet werden.

Antworten mit Beispielen aus der Praxis wären besser.


Einige Klarstellungen:

  • Bei dieser Frage geht es nicht darum, ob Sie die Korrektheit des Codes nachweisen können oder nicht. Nehmen wir standardmäßig an, dass nicht der gesamte Code innerhalb eines angemessenen Zeitraums als korrekt erwiesen werden kann, sondern dass einige Codeteile korrekt sein können. Zum Beispiel ist es sehr einfach, die Richtigkeit eines FizzBuzz-Moduls nachzuweisen. Für einen Cloud-basierten Datensynchronisierungsdienst nicht sehr einfach.

  • Innerhalb dieser Grenzen stellt die Frage Folgendes: Beginnen Sie mit der Annahme, dass eine Codebasis in zwei Teile unterteilt ist: [I] Teile, die sich als richtig erwiesen haben [II] Teile, die sich nicht als richtig erwiesen haben, aber manuell auf ihre Funktion getestet wurden.

  • Ich möchte TDD-Praktiken auf diese Codebasis anwenden, die sie bisher nicht hatte. Die Frage lautet wie folgt: Sollte TDD auf jedes einzelne Modul angewendet werden, oder würde es ausreichen, sie nur auf Module anzuwenden, die sich als nicht korrekt erwiesen haben?

  • "Bewährt richtig" bedeutet, dass Sie dieses Modul als vollständig funktional betrachten können, dh es basiert nicht auf einem globalen oder äußeren Zustand außerhalb von sich selbst und verfügt über eine vollständig eigene API für E / A, der andere Module folgen müssen, die mit ihm interagieren . Es ist nicht möglich, dieses Modul durch Ändern des Codes außerhalb des Moduls zu "beschädigen". Im schlimmsten Fall können Sie ihn missbrauchen und formatierte Fehlermeldungen erhalten.

  • Natürlich gibt es in jeder Regel Ausnahmen. Compiler-Fehler in neuen Compiler-Versionen können zu Fehlern in diesem Modul führen. Dieselben Fehler können jedoch auch bei Tests auftreten, die sie getestet haben, und zu einem falschen Sicherheitsgefühl bei Tests führen, die nicht mehr wie beabsichtigt funktionieren. Das Fazit ist, dass Tests keine magische Lösung sind, sondern eine weitere Schutzschicht. In dieser Frage wird die Frage erörtert, ob diese Schutzschicht im konkreten Fall eines Moduls, das sich als richtig erwiesen hat, die Mühe wert ist (nehmen Sie an, dass es war in der Tat).

Kylee
quelle
10
Der Nachweis der "Code-Korrektheit" könnte schwieriger werden, als Sie denken.
πάντα ῥεῖ
34
Ich habe es zwar genossen, etwas über Ihren Arbeitsplatz und Ihre Arbeitshistorie zu lernen, aber ich habe fast mehrmals aufgehört zu lesen, denn manchmal ist es wirklich wichtig, dass Sie Ihre Ergebnisse maximieren und die Aufmerksamkeit Ihres Lesers auf sich ziehen, damit er Um Ihr Wissen und das der Community zu stärken, müssen Sie ... auf den Punkt kommen . Bitte kürzen Sie Ihre Frage auf die wichtigsten Punkte.
MetaFight
10
Was Sie beschreiben, ist kein Prozess des "Nachweises der Richtigkeit" des Codes. Diese Art von Prozess ist drastisch anders. Außerdem fällt es mir schwer zu akzeptieren, dass Sie Code auf eine Weise erstellen können, die sich nur durch einen Blick darauf als "richtig" erweisen lässt. Ich sah viel Code, der trivial und "korrekt" schien, nur um vollständig zerquetscht zu werden, wenn er einem robusten automatisierten Test unterzogen wurde.
Euphoric
8
"Hüten Sie sich vor Fehlern im obigen Code. Ich habe es nur als richtig erwiesen, nicht ausprobiert." -Donald Knuth.
Neil
6
Ihre Frage macht keinen Sinn. TDD bedeutet, dass die Tests die Entwicklung vorantreiben. Mit anderen Worten, Sie haben kein Design, keine Architektur, keinen Code, es sei denn, Sie haben einen Test dafür. Wie in aller Welt wenden Sie "TDD auf Code an, der sich als richtig erwiesen hat", wenn es nach der Definition von TDD keinen Code gibt, der sich als richtig erweisen könnte ?
Jörg W Mittag

Antworten:

20

Ja.

Beweise sind in Ordnung, wenn sie verfügbar sind, aber selbst zu den besten Zeiten beweisen sie nur, dass ein einzelnes Codebit wie erwartet funktioniert (für alle Eingaben - Berücksichtigung von Unterbrechungen während eines Vorgangs - wie wäre es, wenn der Speicher knapp wird? ? Festplattenfehler? Netzwerkfehler?).

Was passiert, wenn es sich ändert?

Tests sind großartig, da sie als impliziter Vertrag darüber dienen, was der Code tun soll. Sie bieten ein Gerüst, damit Ihr neuer Praktikant mit einem gewissen Maß an Vertrauen Änderungen vornehmen kann. Alles über schnelle, klare Ergebnisse: bestanden oder nicht bestanden.

Und ehrlich gesagt kann ich einen Praktikanten coachen, um in wenigen Monaten brauchbare Unit-Tests zu schreiben. Ich bezweifle, dass irgendjemand in meinem Team (ich selbst eingeschlossen) Beweise erstellen kann, die alles garantieren, was für nicht trivialen Code von Bedeutung ist. geschweige denn schnell und genau.

Telastyn
quelle
Derselbe Code, dessen Beweis nicht trivial wäre, wäre auch nicht trivial zu testen. Ein Netzwerkfehler oder ein Festplattenfehler kann viele Formen annehmen. Wie können Sie sicher sein, dass Ihre Tests jedes einzelne mögliche Szenario abdecken? Sie werden höchstwahrscheinlich jedes einzelne Szenario abdecken, das Sie sich vorstellen können, aber nicht unbedingt jedes einzelne Szenario im wirklichen Leben. Sie können nicht einfach blind davon ausgehen, dass jede Änderung nicht unterbrochen wird, nur weil Sie Tests durchgeführt haben. Es ist nur eine weitere Schutzschicht. Tests sind wichtig, aber keine Wunderwaffe.
Kylee
6
@Kylee - keine Beleidigung, aber Sie scheinen den Aufwand und die Fähigkeiten, die erforderlich sind, um einen Korrektheitsnachweis zu erbringen, stark zu unterschätzen (oder den Aufwand und die Fähigkeiten, die erforderlich sind, um einige automatisierte Tests zusammenzustellen, stark zu überschätzen).
Telastyn
Vielleicht haben Sie Recht, und ich überschätze höchstwahrscheinlich den Aufwand beim Zusammenstellen von Tests, weil ich damit unerfahren bin (ehrlich gesagt, es sind weniger die "Zusammenstellen von Tests", die mir Sorgen machen, als vielmehr das tatsächliche Ausführen der Tests. Für große und sich schnell ändernde Projekte ist dies an sich keine vernachlässigbare Zeitsenke. In jedem Fall hat dies nichts mit der Frage zu tun. In der Frage heißt es eindeutig: Angenommen, Sie haben Code, der sich bereits als richtig erwiesen hat. Gibt es noch einen Grund, Unit-Tests dafür zu schreiben?
Kylee
1
For large & rapidly changing projectsJe anfälliger für Änderungen, desto notwendiger sind die Tests, da ein sich ändernder Code aufgrund neuer Fehler oder unerwarteter Verhaltensweisen viel häufiger fehlschlägt als Code, der sich kaum ändert. Es ist eine Frage der Wahrscheinlichkeit. Auch wenn es sich nicht oft ändert, kann das während der Entwicklung gewonnene Wissen nach einer Weile verloren gehen oder in Vergessenheit geraten. Tests sind auch materialisiertes Wissen, das die Lernkurve erheblich verkürzen kann. Sind Codierungstests zeitaufwändig? Ja. Verteuert es das Projekt? Nein, auf lange Sicht billiger machen .
Laiv
3
@Kylee Selbst wenn Sie beweisen könnten, dass ein Code korrekt ist, befinden Sie sich bestenfalls in der Situation, dass niemand diesen Code ändern oder Funktionen hinzufügen darf. dies würde Ihren Beweis ungültig machen. Wie bereits in dieser Antwort hervorgehoben, können Sie mit Tests Ihren Code sicher ändern. Auch wenn die Person, die es ändert, ein unerfahrener Praktikant ist. Selbst wenn ein Codeblock zu 100% korrekt ist, bedeutet dies nicht, dass Sie ihn niemals ändern müssen (z. B. um eine neue Funktion hinzuzufügen, die von einem Kunden benötigt wird, oder um eine reale Einschränkung zu erfüllen, die in Ihrem Beweis nicht berücksichtigt wird).
Brandin
5

Wir wissen es nicht. Wir können Ihre Frage nicht beantworten.

Während Sie viel Zeit damit verbringen, diesen Prozess zu erklären, der jetzt zu jedermanns Zufriedenheit zu funktionieren scheint, erzählen Sie uns nur einen kleinen Teil dessen, was tatsächlich passiert.

Nach meiner Erfahrung ist das, was Sie beschreiben, eine extreme Seltenheit, und ich bin skeptisch, dass es tatsächlich Ihr Prozess und Ihre Herangehensweise an das Codieren ist, die tatsächlich zu einer geringen Fehleranzahl in Ihren Anwendungen führen. Möglicherweise gibt es viele andere Faktoren, die Ihre Anwendungen beeinflussen, und Sie sagen uns nichts über diese Faktoren.

Wir wissen also nicht, ob TDD Ihnen helfen wird oder nicht, obwohl Sie Ihre genaue Entwicklungsumgebung und -kultur nicht kennen. Und wir können Tage damit verbringen, darüber zu diskutieren und zu streiten.

Wir können Ihnen nur eine Empfehlung geben: Probieren Sie es aus. Experiment. Lern es. Ich weiß, dass Sie versuchen, sich mit geringstem Aufwand zu entscheiden, aber das ist nicht möglich. Wenn Sie wirklich wissen möchten, ob TDD in Ihrem Kontext funktioniert, können Sie dies nur herausfinden, indem Sie tatsächlich TDD ausführen. Wenn Sie es tatsächlich lernen und auf Ihre Anwendung anwenden, können Sie es mit Ihrem Nicht-TDD-Prozess vergleichen. Es kann sein, dass TDD tatsächlich Vorteile hat und Sie sich dafür entscheiden, es beizubehalten. Oder es kann sich herausstellen, dass TDD nichts Neues bringt und Sie nur verlangsamt. In diesem Fall können Sie auf Ihren vorherigen Prozess zurückgreifen.

Euphorisch
quelle
5

Der Hauptzweck von (Einheits-) Tests besteht darin, den Code zu schützen und sicherzustellen, dass er nicht durch spätere Änderungen unbemerkt bleibt. Wenn der Code zum ersten Mal geschrieben wird, wird er viel Aufmerksamkeit erhalten und überprüft. Und dafür haben Sie vielleicht ein überlegenes System.

Sechs Monate später, wenn jemand anderes an etwas arbeitet, das scheinbar nichts damit zu tun hat, kann es kaputt gehen und Ihr Super-Duper-Code-Korrektheitsprüfer wird es nicht bemerken. Ein automatischer Test wird.

Martin Maat
quelle
1
Dies wird viel zu oft übersehen. Ja, es ist schmerzhaft, sicherzustellen, dass der Code jetzt Unit-Tests enthält. Dies zahlt sich jedoch um ein Vielfaches aus, wenn ein Junior-Entwickler eine einfache Änderung vornimmt und Unit-Tests sofort anzeigen, dass er etwas anderes kaputt gemacht hat. Ich war vor Jahrzehnten der Junior-Entwickler, der etwas kaputt gemacht hat und die gesamte Veröffentlichung hat sich verzögert. Während meine Kollegen zu dieser Zeit sehr tolerant waren und meinen Rücken hatten, als die Manager auf und ab sprangen, hätte das gesamte Szenario im Nachhinein vermieden werden können, wenn Unit-Tests durchgeführt worden wären.
Robbie Dee
5

Ich möchte TDD-Praktiken auf diese Codebasis anwenden, die sie bisher nicht hatte.

Dies ist der schwierigste Weg, TDD zu lernen. Je später Sie testen, desto mehr kostet das Schreiben von Tests und desto weniger Zeit haben Sie damit, sie zu schreiben.

Ich sage nicht, dass es unmöglich ist, Tests in eine vorhandene Codebasis nachzurüsten. Ich sage, dass dies wahrscheinlich niemanden zu einem TDD-Gläubigen machen wird. Das ist harte Arbeit.

Es ist eigentlich am besten, TDD das erste Mal an etwas Neuem und zu Hause zu üben. Auf diese Weise lernen Sie den wirklichen Rhythmus. Wenn Sie dies richtig machen, werden Sie feststellen, dass es süchtig macht.

Die Frage stellt Folgendes: Sollte TDD auf jedes einzelne Modul angewendet werden?

Das ist strukturelles Denken. Sie sollten nicht Dinge wie das Testen jeder Funktion, Klasse oder jedes Moduls sagen. Diese Grenzen sind für das Testen nicht wichtig und sollten sich sowieso ändern können. Bei TDD geht es darum, ein überprüfbares Verhaltensbedürfnis zu etablieren und sich nicht darum zu kümmern, wie es befriedigt wird. Wenn es nicht so wäre, könnten wir nicht umgestalten.

oder würde es ausreichen, sie nur auf Module anzuwenden, die sich als nicht korrekt erwiesen haben?

Es reicht aus, sie dort anzuwenden, wo Sie sie brauchen. Ich würde mit neuem Code beginnen. Wenn Sie früh testen, erhalten Sie viel mehr zurück als spät. Tun Sie dies nicht bei der Arbeit, bis Sie genug geübt haben, um es zu Hause zu meistern.

Wenn Sie gezeigt haben, dass TDD mit dem neuen Code bei der Arbeit effektiv ist und sich sicher genug fühlt, den alten Code zu übernehmen, würde ich mit dem bewährten Code beginnen. Der Grund dafür ist, dass Sie sofort sehen können, ob die Tests, die Sie schreiben, den Code in eine gute Richtung lenken.

Meine Hauptfrage lautet: Würde TDD irgendeinen Zweck für Code erfüllen, wenn ich die Korrektheit des Codes bereits nachweisen kann?

Tests beweisen nicht nur die Richtigkeit. Sie zeigen Absicht. Sie zeigen, was gebraucht wird. Sie weisen auf einen Weg zur Veränderung hin. Ein guter Test besagt, dass es mehrere Möglichkeiten gibt, diesen Code zu schreiben und das zu bekommen, was Sie wollen. Sie helfen neuen Programmierern zu sehen, was sie tun können, ohne alles zu beschädigen.

Erst wenn Sie das erledigt haben, sollten Sie in den unbewiesenen Code eintauchen.

Eine Warnung vor Eiferern: Sie scheinen Erfolg zu haben und werden daher wahrscheinlich nicht kopfüber springen. Aber andere, die sich beweisen wollen, werden nicht so zurückhaltend sein. TDD kann übertrieben werden. Es ist erstaunlich einfach, eine Reihe von Tests zu erstellen, die das Refactoring tatsächlich beeinträchtigen, da sie trivalente und bedeutungslose Dinge blockieren. Wie kommt es dazu? Weil Leute, die Tests vorführen wollen, nur Tests schreiben und niemals umgestalten. Lösung? Lass sie umgestalten. Lassen Sie sie mit Funktionsänderungen umgehen. Je früher desto besser. Das zeigt Ihnen schnell die nutzlosen Tests. Sie beweisen Flexibilität durch Biegen.

Eine Warnung vor struktureller Kategorisierung: Einige Leute werden darauf bestehen, dass eine Klasse eine Einheit ist. Einige nennen jeden Test mit zwei Klassen einen Integrationstest. Einige werden darauf bestehen, dass Sie die Grenze x nicht überschreiten und es einen Komponententest nennen können. Anstatt sich um irgendetwas davon zu kümmern, rate ich Ihnen, sich darum zu kümmern, wie sich Ihr Test verhält. Kann es in Sekundenbruchteilen laufen? Kann es parallel zu anderen Tests durchgeführt werden (nebenwirkungsfrei)? Kann es ausgeführt werden, ohne andere Dinge zu starten oder zu bearbeiten, um Abhängigkeiten und Voraussetzungen zu erfüllen? Ich habe diese Überlegungen vorgezogen, wenn es sich um eine Datenbank, ein Dateisystem oder ein Netzwerk handelt. Warum? Weil diese letzten drei nur Probleme sind, weil sie die anderen Probleme verursachen. Gruppieren Sie Ihre Tests danach, wie Sie erwarten können, dass sie sich verhalten. Nicht die Grenzen, die sie zufällig überschreiten. Dann wissen Sie, was Sie von jeder Testsuite erwarten können.

Ich habe Leute gesehen, die sagten, sie wollten TDD nicht verwenden, weil es zu viel Overhead hätte, und TDD-Unterstützer verteidigen es, indem sie sagen, dass es nicht viel Overhead gibt, wenn man sich daran gewöhnt hat, TDD die ganze Zeit zu schreiben.

Diese Frage hat hier bereits Antworten .

candied_orange
quelle
1

Bei der testgetriebenen Entwicklung geht es mehr um das Prototyping und das Brainstorming einer API als um das Testen. Die erstellten Tests sind oft von schlechter Qualität und müssen schließlich weggeworfen werden. Der Hauptvorteil von TDD besteht darin, vor dem Schreiben der API-Implementierung zu bestimmen, wie eine API verwendet wird. Dieser Vorteil kann auch auf andere Weise erzielt werden, beispielsweise durch Schreiben einer API-Dokumentation vor der Implementierung.

Korrektheitsnachweise sind immer wertvoller als Tests. Tests beweisen nichts. Um Korrektheitsnachweise produktiv nutzen zu können, ist es jedoch hilfreich, einen automatisierten Proofprüfer zu haben, und Sie müssen mit Verträgen arbeiten (Design by Contract oder vertragsbasiertes Design).

In der Vergangenheit habe ich bei der Arbeit an kritischen Codeabschnitten versucht, manuelle Korrektheitsnachweise zu erbringen. Selbst informelle Beweise sind wertvoller als automatisierte Tests. Sie benötigen die Tests jedoch weiterhin, es sei denn, Sie können Ihre Proofs automatisieren, da die Benutzer in Zukunft Ihren Code beschädigen werden.

Automatisierte Tests implizieren keine TDD.

Frank Hileman
quelle
Durch das Brainstorming einer API und eines Vertragsentwurfs gehe ich bereits Probleme an. Daher möchte ich sagen, dass mir Ihre Antwort gefällt, aber andere Quellen sagen: "In der testgetriebenen Entwicklung beginnt jede neue Funktion mit dem Schreiben eines Tests." Sie sagten Dinge, denen ich zustimme, überzeugten mich aber nicht, den TDD-Ansatz zu verwenden. "Automatisierte Tests implizieren kein TDD", ok, aber was bedeutet TDD dann im Gegensatz zum einfachen Befolgen allgemeiner Best Practices?
Kylee
1
Obwohl ich der Meinung bin, dass TDD häufig das Brainstorming einer API (IMO) umfasst, ist dies manchmal eine schlechte Sache . Die API sollte nicht (unbedingt) auf Testbarkeit ausgelegt sein, sondern sollte so konzipiert sein, dass sie von Ihren Clients reibungslos verwendet wird und für die beteiligten Klassen / Codes einen Sinn ergibt. Allzu oft habe ich einen Testautor gesehen, der sagte: "Fügen String getSomeValue()wir hier hinzu , damit wir es testen können", wenn dies für das Gesamtdesign keinen Sinn ergibt. Sicher, Sie könnten diese Funktion später entfernen, aber meiner Erfahrung nach ist das selten.
user949300
1
@ user949300, Es gibt eine große Überschneidung zwischen dem Entwerfen einer testbaren API und einer API, die so konzipiert ist, dass sie von Ihren Kunden reibungslos verwendet werden kann. Das Hinzufügen von unnötigem Code für den Test zeigt, dass Sie ein schlechtes Design haben. Allzu oft vergessen API-Autoren das Debuggen von Fehlern mit einer API. Wenn Sie etwas Testbares UND Nützliches für den Benutzer schreiben, müssen Sie über diese Dinge nachdenken ... ohne Implementierungsdetails in Ihre Benutzeroberfläche zu übertragen.
Berin Loritsch
@ user949300 Die Hauptbeschwerde über TDD ist wahrscheinlich die Art und Weise, wie die API für "Testbarkeit" im Sinne der Einheit geändert wird, sodass Dinge, die normalerweise gekapselt sind, offengelegt werden. Die Beschwerde Nummer zwei ist wahrscheinlich, dass sie im Laufe der Zeit nicht gut skaliert.
Frank Hileman
@Kylee Automatisierte Tests sind älter als das Schlagwort "TDD". Der Unterschied besteht darin, dass automatisierte Tests einfach das sind, was Ihrer Meinung nach getestet werden sollte - es gibt weder ein Dogma noch eine bestimmte Reihenfolge, in der Sie sie schreiben. Es gibt auch keinen Schwerpunkt auf Unit-vs-Integrationstests.
Frank Hileman
0

A) Wenn Sie den Code lesen und sich davon überzeugen, dass er korrekt ist, ist dies nicht annähernd der Beweis, dass er korrekt ist. Warum sonst überhaupt Tests schreiben?

B) Wenn Sie den Code ändern, möchten Sie Tests ausführen lassen, die zeigen, dass der Code immer noch korrekt ist oder nicht.

Josh
quelle
Dies scheint lediglich die Punkte zu wiederholen, die in der Top-Antwort , die einige Wochen zuvor veröffentlicht wurde, gemacht (und viel besser erklärt) wurden
Mücke
@gnat Es ist eine prägnantere Antwort für etwas, für das kein Roman geschrieben werden muss. Bitte versuchen Sie hier etwas beizutragen.
Josh
-1

Ich möchte darauf hinweisen, dass Sie im Endspiel Zeit sparen, wenn Sie erst einmal daran gewöhnt sind, TDD effektiv einzusetzen. Es erfordert Übung, um zu lernen, wie man TDD effektiv einsetzt, und es hilft nicht, wenn Sie sich in einer Zeitkrise befinden. Wenn Sie lernen, wie Sie es am besten nutzen können, empfehle ich, mit einem persönlichen Projekt zu beginnen, bei dem Sie mehr Spielraum und weniger Zeitplandruck haben.

Sie werden feststellen, dass Ihr anfänglicher Fortschritt langsamer ist, während Sie mehr experimentieren und Ihre API schreiben. Mit der Zeit werden Sie schneller Fortschritte machen, da Ihre neuen Tests ohne Änderung des Codes bestanden werden und Sie eine sehr stabile Basis haben, auf der Sie aufbauen können. Im späten Spiel müssen Sie für Code, der nicht mit TDD erstellt wurde, viel mehr Zeit im Debugger verbringen, um herauszufinden, was falsch läuft, als erforderlich sein sollte. Sie haben auch ein höheres Risiko, etwas zu beschädigen, das früher mit neuen Änderungen gearbeitet hat. Bewerten Sie die Wirksamkeit von TDD im Vergleich zur Nichtverwendung bis zur Fertigstellung.

Trotzdem ist TDD nicht das einzige Spiel in der Stadt. Sie können BDD verwenden, das eine Standardmethode zum Ausdrücken des Verhaltens einer Full-Stack-Anwendung verwendet, und von dort aus die Richtigkeit der API bewerten.

Ihr gesamtes Argument hängt vom "Nachweis der Code-Korrektheit" ab. Sie benötigen also etwas, das die Code-Korrektheit definiert. Wenn Sie kein automatisiertes Tool verwenden, um zu definieren, was "richtig" bedeutet, ist die Definition sehr subjektiv. Wenn Ihre Definition von korrekt auf dem Konsens Ihrer Kollegen basiert, kann sich dies an einem bestimmten Tag ändern. Ihre Definition von korrekt muss konkret und überprüfbar sein, was auch bedeutet, dass sie von einem Tool bewertet werden kann. Warum nicht eins benutzen?

Der größte Gewinn bei der Verwendung automatisierter Tests jeglicher Art besteht darin, dass Sie überprüfen können, ob Ihr Code auch dann korrekt bleibt , wenn Betriebssystem-Patches schnell und effizient angewendet werden. Führen Sie Ihre Suite aus, um sicherzustellen, dass alles erfolgreich ist. Wenden Sie dann den Patch an und führen Sie die Suite erneut aus. Machen Sie es noch besser zu einem Teil Ihrer automatisierten Build-Infrastruktur. Jetzt können Sie überprüfen, ob Ihr Code nach dem Zusammenführen von Code von mehreren Entwicklern korrekt bleibt.

Meine Erfahrung mit TDD hat mich zu folgenden Schlussfolgerungen geführt:

  • Es ist großartig für neuen Code und schwierig für das Ändern älterer Systeme
  • Sie müssen noch wissen, was Sie erreichen möchten (dh einen Plan haben)
  • Langsam zu starten, spart aber später Zeit
  • Zwingt Sie dazu, darüber nachzudenken, wie Sie die Korrektheit und das Debuggen aus Benutzersicht überprüfen können

Meine Erfahrung mit BDD hat mich zu folgenden Schlussfolgerungen geführt:

  • Es funktioniert sowohl für Legacy- als auch für neuen Code
  • Es validiert den gesamten Stapel und definiert die Spezifikation
  • Langsamer in Betrieb zu nehmen (hilft, jemanden zu haben, der das Toolset kennt)
  • Es müssen weniger Verhaltensweisen definiert werden als Unit-Tests

Definition von Richtig: Ihr Code entspricht den Anforderungen. Dies lässt sich am besten mit BDD überprüfen, das eine Möglichkeit bietet, diese Anforderungen auf eine für Menschen lesbare Weise auszudrücken und zur Laufzeit zu überprüfen.

Ich spreche nicht von Korrektheit in Bezug auf mathematische Beweise, was nicht möglich ist. Und ich bin es leid, dieses Argument zu haben.

Berin Loritsch
quelle
Ein wunderbarer Beitrag, der sich mit einem Problem befasst, bei dem ich zunächst über TDD nachgedacht habe: Die derzeitige Definition von "Code-Korrektheit" ist in der Tat ein Konsens der Kollegen. Ich mache mir Sorgen, dass diese Methode nicht mehr funktioniert, wenn sich das Team in Zukunft ändert. Aber wie würde TDD das lösen? Während alte Tests neue Teammitglieder davon abhalten können, alte Funktionen leicht zu beschädigen, schreiben sie möglicherweise unvollständige Tests für zukünftige Funktionen, was immer noch zu Problemen führen würde. Letztendlich setzen beide Methoden das Vertrauen in Ihr Team voraus. Ich habe noch nie von BDD gehört, also werde ich das auch überprüfen. Vielen Dank.
Kylee
2
"Sie können überprüfen, ob Ihr Code korrekt bleibt" Nein. Nicht einmal annähernd. Sie können höchstens behaupten, dass der Test, den Sie ausgeführt haben, noch besteht.
Gebogen am
@ Kylee, BDD spricht dieses Problem besser an. BDD lässt Sie eine Spezifikation schreiben, die überprüfbar ist. Die Spezifikation ist in Ihrer natürlichen Sprache geschrieben, um Hooks für den tatsächlichen Testcode zu erstellen, der die Spezifikation überprüft. Das verbindet zwei Anliegen, kommuniziert die tatsächlichen Anforderungen und setzt sie durch.
Berin Loritsch
1
@Bent, bitte streiten Sie nicht über "Korrektheit" in Bezug auf mathematische Beweise. Das ist nicht das Gesprächsthema oder was ich vermitteln wollte. Aufgrund von Erfahrungen neigen Leute, die Kommentare wie Ihre veröffentlichen, dazu, dies zu berücksichtigen. Sie können absolut überprüfen, ob der Code den Anforderungen entspricht. Das ist die Arbeitsdefinition von richtig, von der ich spreche.
Berin Loritsch
Das Problem ist, dass Sie zu einer Definition von "korrekt" fahren, bei der der Code die von Ihnen definierten Tests bestehen muss. Jeder andere Satz von Eingaben ist ein undefiniertes Verhalten, und die Ausgabe ist beliebig. Dies entspricht nicht wirklich den Anforderungen der meisten Benutzer.
Simon B