Vor etwas mehr als einem Jahr hatte ich das Glück, eine neunmonatige Pause von der Arbeit machen zu können. Ich entschied, dass ich in dieser Zeit meine C # -Fähigkeiten verbessern würde. Ich begann an einer Reihe von Projekten zu arbeiten und zwang mich, TDD zu folgen.
Es war ein ziemlich aufschlussreicher Prozess.
Anfangs war es schwierig, aber im Laufe der Zeit lernte ich, mehr testbaren Code zu schreiben (was, wie sich herausstellt, mehr SOLID-Code ist) und schärfte dabei auch meine Fähigkeiten im OO-Design.
Jetzt bin ich wieder in der Belegschaft und merke etwas Seltsames.
Ich folge TDD lieber nicht.
Ich finde, TDD verlangsamt mich und erschwert das Entwerfen einer sauberen Anwendung.
Stattdessen habe ich einen etwas (massiv) anderen Ansatz gewählt:
- Wählen Sie ein vertikales Stück Arbeit
- Entwickeln Sie einen funktionierenden Prototyp
- Refactor bis alles schön aufgeräumt ist
- Lehnen Sie sich zurück und schätzen Sie den SOLIDEN und testbaren Code, den ich geschrieben habe.
Möglicherweise haben Sie bemerkt, dass Schritt 1 nicht "die öffentliche Oberfläche meines Testziels definieren" und Schritt 2 nicht "den Bejesus von dieser öffentlichen Oberfläche testen" war. Möglicherweise haben Sie auch bemerkt, dass keiner der Schritte Tests umfasst. Ich schreibe testbaren Code, aber ich teste ihn noch nicht.
Nun möchte ich klarstellen, dass ich nicht auf irgendwelche Tests verzichte. Der Code, den ich schreibe, funktioniert . Es funktioniert, weil ich es manuell teste.
Ich möchte auch klarstellen, dass ich auch nicht auf alle automatisierten Tests verzichte. Hier ist mein Prozess anders. Und deshalb stelle ich diese Frage.
TDD in der Theorie. Nicht in der Praxis.
Mein Prozess hat sich ein wenig weiterentwickelt und ich habe eine Balance zwischen TDD und keinen Tests gefunden, die ich als sehr produktiv und auch einigermaßen sicher empfinde. Es geht wie folgt:
- Implementieren Sie eine vertikale Arbeitsaufgabe mit Blick auf das Testen, schreiben Sie jedoch keine Tests.
- Wenn Sie später (z. B. einen Monat später) auf der Straße sind, muss dieses Segment geändert werden
- Schreiben Sie Unit-Tests, Integrationstests, Verhaltenstests usw., die sicherstellen, dass die Arbeit korrekt ist
- Ändern Sie den Code
- Wenn das Slice nicht geändert werden muss,
- Nichts tun
Indem ich einfach die Belastung durch das Schreiben von Tests von vor dem Schreiben des Codes auf vor dem Ändern des Codes verlagere , konnte ich viel mehr Arbeitscode produzieren. Und wenn ich zum Schreiben von Tests komme, schreibe ich viel weniger, aber fast genauso viel Grund (höherer ROI).
Ich mag diesen Prozess, bin aber besorgt, dass er möglicherweise nicht gut skaliert. Der Erfolg hängt davon ab, dass Entwickler fleißig Tests schreiben, bevor sie etwas ändern. Und das scheint ein ziemlich großes Risiko zu sein. TDD birgt jedoch das gleiche Risiko.
Also, gehe ich zur [BT] DD-Hölle, oder ist dies eine übliche Form von pragmatischem Codieren und Testen?
Ich würde gerne so weitermachen. Was kann ich tun, damit dieser Prozess langfristig funktioniert?
Hinweis:Ich bin der einzige Entwickler in meinen Projekten und für alles verantwortlich: Erfassung der Anforderungen, Design, Architektur, Tests, Bereitstellung usw. Ich vermute, dass dies der Grund ist, warum mein Prozess funktioniert.
quelle
If that slice doesn't need modification
. lizkeogh.com/2012/06/24/beyond-test-driven-developmentAntworten:
Damit der Prozess auf lange Sicht funktioniert, würde ich die Tests schreiben, wenn der Code geschrieben wird.
Was Ihrem Ansatz zu widersprechen scheint. Wie auch immer Sie die Frage gestellt haben, ich gebe Ihnen mein Einverständnis:
Sie müssen die Tests nicht vor dem Code schreiben. vergiss diese Reinheit. Allerdings sollten Sie die Tests schreiben um diese Zeit.
Sobald der Code funktioniert, Sie ihn ein wenig verbessert und einige Fehler behoben haben (wir sprechen hier von einer Zeitspanne von Stunden), sind Sie an einem Punkt angelangt, an dem Sie das maximale Wissen darüber haben, was der Code tut. Dies ist eine großartige Zeit, um Tests zu schreiben, die Ihr Wissen erfassen.
Dies bis später zu belassen bedeutet, dass das Wissen (natürlich) im Laufe der Zeit abnimmt.
Dies bedeutet auch, dass Sie, sollten Sie jemals abreisen und jemand anderes die Leitung übernehmen, nicht die unmittelbare technische Schuld haben, nicht (durch Tests) dokumentiert zu haben, was was tut.
Am allermeisten kann "eines Tages" nicht kommen. Sie können entweder von einem Bus angefahren werden oder in den Bus einsteigen, um neue Abenteuer zu erleben.
Schließlich sind manuelle Tests nicht skalierbar und decken häufig nicht alle vom Endbenutzer verwendeten Geräte ab.
quelle
Obwohl es schwierig ist, TDD zu 100% umzusetzen, liegt ein Fehler in Ihrem Ansatz vor
Implementieren Sie einen vertikalen Arbeitsabschnitt
1.1 1 Jahr vergeht ....
1.2 Ein neuer Entwickler beginnt mit der Arbeit am Projekt
Wenn das Slice geändert werden muss
2.3 Analysieren der Namen und Parameter der 'Clean Coding'-Methode' GetUnicorn (colourOfUnicorn) '
2.4 Lesen Sie die XML-Kommentare 'Bekommt ein goldenes Einhorn (zum Reiten) (obvs)'
2.5 Jage den ursprünglichen Entwickler
2.6 Ich hoffe, sie erinnern sich daran, was der Code tun soll
2.7 Lassen Sie sie alles erklären
Schreiben Sie Unit-Tests, Integrationstests, Verhaltenstests usw., die hoffentlich sicherstellen , dass die Arbeit korrekt ist
Ich denke, Sie haben Recht zu erkennen, dass Komponententests wirklich ihren Wert zeigen, wenn Änderungen erforderlich sind.
quelle
Ich stimme sowohl Daniel Hollinrake als auch Ewan zu, dass der erste wichtige Punkt, warum Ihr Test nur bei Änderung gut funktioniert, ist:
und dass ein wahrscheinlicher zweiter wichtiger Punkt ist:
Ich glaube nicht, dass TDD den alleinigen Programmierern einen enormen Produktivitätsschub bringt, und es kann die Qualität Ihres Codes nicht wesentlich verbessern, wenn Sie bereits guten, sauberen Code schreiben.
TDD wird jedoch mit Sicherheit die Qualität des Codes für arme / unerfahrene / veraltete Programmierer verbessern, insbesondere wenn es an der Zeit ist, den Code zu ändern, ohne etwas anderes zu beschädigen. Und umso mehr, wenn die Person, die den Code ändert, nicht dieselbe Person ist, die den Code ursprünglich geschrieben hat, oder mehrere Monate dazwischen vergangen sind.
Mit anderen Worten, ich denke, TDD ist sowohl eine gute Methode, um die Qualität Ihres Codes zu verbessern (wie Sie sich selbst eingestehen), als auch (und noch wichtiger) eine Art Absicherung, wenn Sie mit durchschnittlichen oder mittelmäßigen Programmierern zusammenarbeiten (etwa von einem anderen) Abteilung oder ein anderes Unternehmen), was weitaus häufiger vorkommt, als allein zu arbeiten.
quelle
Für mich scheint der Schlüssel folgender zu sein:
Dies funktioniert für Sie und Sie produzieren netten, sauberen Code (nehme ich an!). Ich würde nur sagen, dass Sie ein Test-Gurtzeug erstellen müssen, damit andere Entwickler zuversichtlich Änderungen vornehmen können. Auch das Testgeschirr sorgt für Konsistenz im Verhalten des Codes.
Ich denke, Ihr Ansatz ähnelt meinem. Normalerweise bin ich der einzige Entwickler meiner Projekte. Ich habe festgestellt, dass ich dank TDD kleinere Funktionen und saubereren Code schreiben kann, aber ich füge Tests hinzu, während ich den Code als Test-Harness schreibe. Auf diese Weise kann ich, während sich der Code weiterentwickelt und die Funktionalität ändert, einigermaßen sicher sein, Änderungen vorzunehmen.
Ein zweiter Grund für das Schreiben von Tests ist, dass ich denke, dass sie eine Form der Dokumentation sind. Sie können meine Gründe dafür erklären, warum eine Funktion erstellt wurde. Aber hier denke ich mehr über behaviour Driven Development nach.
quelle
Beim Unit Testing geht es darum, das Problem der Codewartung anzugehen. Es gibt zwar Leute, die behaupten, dass sie mit TDD schneller Code schreiben als ohne, aber ich bin nicht überrascht, dass Sie in der Lage sind, mehr neuen Code zu schreiben, ohne Tests zu schreiben.
Die Probleme, die ich beim Schreiben von Tests sehen kann, bevor Sie sie ändern:
Ich muss mich oft in Eile verändern
Während Sie möglicherweise insgesamt Zeit sparen, indem Sie Tests nur dann schreiben, wenn Sie sie benötigen, ist nicht alle Zeit gleich. Verbringen Sie 2 Stunden mit dem Schreiben von Tests, um 1 Stunde zu sparen, wenn ich mich im Krisenmodus befinde - es lohnt sich auf jeden Fall.
Es ist einfacher, Tests gleichzeitig mit dem Schreiben des Codes zu schreiben
Um Unit-Tests richtig schreiben zu können, müssen Sie den Code verstehen, den ich teste. Ich benutze Unit-Tests oft als Übung zum Verstehen, aber das Testen vorhandener Codes kann zeitaufwändig sein, da das Verstehen vorhandener Codes zeitaufwändig ist. Vergleichen Sie dies mit dem Schreiben von Tests, während Sie den Code schreiben, und Sie werden ihn viel schneller finden, da Sie den Code bereits verstehen - Sie haben ihn gerade geschrieben!
Michael Feathers Definition von Legacy-Code ist Code ohne Tests. Unabhängig davon, ob Sie mit seiner Definition einverstanden sind, ist klar, dass ein erheblicher Teil der Kosten für die Änderung des vorhandenen Codes dafür verantwortlich ist, dass dieser weiterhin wie erwartet funktioniert. Oft ist nicht einmal klar, wie das erwartete Verhalten ist.
Das Schreiben von Einheiten testet kostenintensive Offsets, indem es ein Verständnis für das richtige Verhalten codiert und "Future Us" eine einfache Möglichkeit bietet, zu überprüfen, ob das Verhalten noch korrekt ist.
quelle
Das ist eine gute Frage, und FWIW werde ich meine zwei Cent einwerfen.
Vor ungefähr einem Jahr programmierte ich in Salesforce, einer Plattform mit einem integrierten Mechanismus, der Sie dazu zwang, nicht unbedingt Tests zu schreiben, bevor Sie programmierten , sondern Tests generell zu schreiben.
Es funktionierte so, dass das System Sie zwang, Tests zu schreiben, und die Anzahl der getesteten Codezeilen in Prozent berechnete. Wenn der gesamte Code in Ihrer gesamten Produktionsinstanz unter 75% gefallen ist, wird Salesforce nicht mehr ausgeführt.
Das Endergebnis war, dass Sie jedes Mal, wenn Sie in Salesforce etwas unternahmen, Tests schreiben oder aktualisieren mussten. Obwohl ich mir sicher bin, dass dies einen enormen Einfluss auf den Marktanteil von Salesforce hat, war es in Bezug auf das Leben eines Entwicklers ein schwerer Ärger .
Die meiste Zeit haben Sie nur versucht, durch ein kleines Ticket zu kommen, und dann kommt das Testen und verdoppelt Ihre Entwicklungszeit für eine Funktion, von der Sie nur wissen, dass sie funktioniert.
Dann durchlief das umständliche Konzept von TDD unsere Abteilung bis hinunter zu unseren Datenbanken. Unsere Architekten wollten alle Aspekte unserer IT-Abteilung einer gründlichen Prüfung unterziehen. Leichte Schmerzen im Arsch, noch größere Schmerzen im Arsch.
TDD hat mir damals noch nie wirklich Sinn gemacht und auch jetzt noch nicht. Viele der Funktionen, die ich in meiner aktuellen Rolle geschrieben habe, basieren auf einem ähnlichen Mechanismus wie dem, den Sie erwähnt haben: in vertikalen Segmenten, die ich verfeinere, bis sie funktionieren. Als ich noch in dieser alten Rolle war, weiß ich oft nicht, was mein Code tun wird, bis ich ihn tatsächlich schreibe. Die Idee, dass ich Code schreiben kann, wird also getestet, um den Code zu steuern, den ich jetzt schreibe. macht für mich keinen Sinn, ist umständlich und meistens Zeitverschwendung.
All das sagte, Tests sind wunderbare und magische Dinge , die alles richtig machen in der Welt . Sie korrigieren Ihren Code, sorgen dafür, dass Ihre App genau das tut, was Sie denken, und im Allgemeinen ist alles reibungsloser. Die Frage ist dann nicht, ob Sie Ihre Tests schreiben, bevor Sie codieren, oder ob Sie nach dem Codieren die Frage stellen, wie viel Zeit Sie für das Testen aufwenden werden. Das ist das eigentliche Problem, zumindest in meiner Erfahrung in der Softwareentwicklung. Testen kostet Zeit und Geld und muss im Rahmen konkurrierender Interessen durchgeführt werden.
Und so stimme ich Ihnen im Allgemeinen zu: TDD ist in der Praxis etwas umständlich und umständlich. An diesem Punkt müssen Sie bedenken, was in Ihrer aktuellen Situation am besten funktioniert . Wenn Sie kritischen Code schreiben, stellen Sie einfach sicher, dass er allgemein getestet wurde. Wenn Sie die Zeit haben, versuchen Sie es mit TDD, und prüfen Sie, ob der Prozess dadurch etwas verbessert wird.
quelle
Ich kann Ihren Ansatz nicht empfehlen.
Wenn ich Ihren Ansatz verwende, würde dies beispielsweise wie folgt aussehen (das Haus ist die Anwendung):
Ihr Ansatz kostet also viel Zeit und viel Wissen, bevor ich das Haus mit Ihrem Ansatz baue. Oder es braucht ein bisschen Zeit! Es ist auch kein schöner Gentleman, andere Schreibtests für Ihren Code durchführen zu lassen, wenn sich die Anforderungen geändert haben.
Es gibt also einen besseren Ansatz, als einen "Prototyp" zu programmieren und mit dem Refactoring zu beginnen. Anstatt einen Prototyp zu programmieren, "erstellen Sie ein Design mit UML Ihrer Anwendung wie folgt.
Sicher, dieser Ansatz erfordert auch einige Kenntnisse in UML, ist aber schnell zu erlernen. Und es ist immer schneller, eine Klasse umzubenennen oder Pfeile in einem Digramm zu verschieben, als dies in Ihrer IDE der Fall ist. Das Erlernen der Verwendung von Test-Frameworks wird am Anfang jedoch anstrengender sein. Am besten ist es, wenn Sie Open Source-Projekte testen und sehen, wie sie funktionieren. Aber wenn Sie eine testgetriebene Anwendung haben, wird die nächste Anwendung viel schneller sein. Und ich finde es ein gutes Gefühl zu wissen, dass alles gut funktioniert.
Deshalb stimme ich die Ansätze nur herab, weil sie für Anfänger sehr zeitaufwendig und schließlich nicht gut sind. Um eine saubere Grenze zwischen Ihrer Struktur und dem Verhalten zu haben, können Sie das domänengesteuerte Design verwenden und unter "Sehr Domäne mit zwei Paketen anordnen" (ein Paket mit dem Namen "Struktur" und das andere mit dem Namen "Verhalten"). Auch für Ihre Tests. Einfaches Beispiel Schauen Sie sich dieses in Java geschriebene Beispiel an.
quelle
Haben Sie nach einer kleinen Änderung jeden möglichen Zweig Ihrer Bedingungen manuell getestet? Wie lange dauert die Rückkopplungsschleife Ihres manuellen Tests? Wie nahe es an der Rückkopplungsschleife liegt, können Sie mit automatisierten Tests feststellen.
Durch automatisierte Tests (egal, ob zuerst oder nicht) können Sie schnell voranschreiten - indem Sie eine schnellere Rückkopplungsschleife für Ihren Code bereitstellen.
Sind Sie sicher, dass Sie daran denken werden, eine Bedingung nach sechs Monaten manuell zu testen? Bitte sagen Sie nicht, dass Sie alle wichtigen zu testenden Bedingungen dokumentieren werden?
Und nochmal: Haben Sie beim Refactoring alle Logik, die vom Refactoring betroffen ist, manuell getestet? Wie lange dauert es, um Änderungen am Refactoring zu testen? Wenn das Refactoring Code bricht, wie lange dauert es, bis Sie einen Grund für Brüche finden?
Schöner und sauberer Code, den Sie genossen haben, ist sehr subjektiv. Ihr Code kann für Sie sauber und vernünftig sein. Die beste Methode, um zu überprüfen, ob Ihr Code wirklich lesbar, verständlich und testbar ist, sind Tests und Codeüberprüfungen, die von anderen Entwicklern durchgeführt wurden.
Sie fanden Ihren Weg sehr produktiv, nur weil Sie nur Entwickler sind, die mit dem Code arbeiten, und ich denke, weil Sie erst anfangen, in diesem Projekt zu arbeiten (Wie alt sind Sie in diesem Projekt, an dem Sie arbeiten? 6 - 8 Monate?).
Sie erinnern sich noch an alles, was Sie geschrieben haben, und können einen Grund für mögliche Probleme erkennen. Ich bin mir ziemlich sicher, dass Sie nach 2-3 Jahren Ihres Projekts von Anfang an Tests schreiben werden - weil Sie sicher sein möchten, dass Sie nichts vergessen.
quelle
Wenn Sie nie Fehler machen, brauchen Sie keine Tests. Die meisten Entwickler machen Fehler, aber wenn Sie dies niemals tun und Sie sicher sind, dass Sie in Zukunft niemals Fehler machen werden (und Sie sind der einzige im Projekt), gibt es wirklich keinen Grund, Zeit damit zu verschwenden, Tests zu schreiben.
Ihre Lösung ist jedoch auf halbem Weg, da Sie beim Ändern von Code das Schreiben von Tests vorschlagen. Gleichzeitig geht Ihre Methode jedoch davon aus, dass Sie bei der Entscheidung, für welche Teile des Codes Tests geschrieben werden sollen, keine Fehler machen werden. Dies funktioniert nur, wenn Sie immer genau wissen, welche Bereiche von einer Änderung betroffen sein können. Ich denke, viele gängige Entwickler (natürlich nicht Sie!) Haben die Erfahrung gemacht, Änderungen vorzunehmen, und dann schlägt ein Test an einer unerwarteten Stelle fehl, weil Sie einen Fehler gemacht haben.
Natürlich sollten eine gute Architektur, SOLID-Prinzipien usw. dies verhindern, aber die meisten Entwickler sind nicht perfekt, und deshalb sind systemübergreifende Tests wertvoll.
quelle