Testgetriebene Entwicklung: Was ist, wenn der Fehler in der Schnittstelle liegt?

8

Ich habe den letzten Kodierungs-Horror-Beitrag gelesen, und einer der Kommentare berührte einen Nerv für mich:

  

Dies ist die Art von Situation, die das testgetriebene Design / Refactoring beheben soll. Wenn (groß if) Sie Tests für die Schnittstellen haben, ist das Umschreiben der Implementierung risikofrei, weil Sie wissen werden, ob Sie alles erfasst haben.

Nun, theoretisch mag ich die Idee der testgetriebenen Entwicklung, aber all die Male, wo ich versucht habe, es zum Laufen zu bringen, ist es nicht besonders gut gelaufen, ich habe die Gewohnheit verloren und als nächstes weiß ich alles Tests, die ich ursprünglich geschrieben habe, bestehen nicht nur nicht, sondern spiegeln nicht mehr das Design des Systems wider.

Es ist alles gut und gut, wenn Sie von Anfang an ein perfektes Design von oben bekommen haben (was meiner Erfahrung nach nie wirklich passiert), aber was ist, wenn Sie nach der Hälfte der Produktion eines Systems bemerken, dass es ein kritischer Fehler im Design? Dann ist es nicht mehr einfach, einzusteigen und "den Fehler" zu beheben, sondern Sie müssen auch alle Tests neu schreiben. Eine grundlegende Annahme war falsch, und jetzt müssen Sie sie ändern. Jetzt ist testgetriebene Entwicklung keine praktische Sache mehr, aber es bedeutet einfach, dass es doppelt so viel Arbeit gibt, alles zu tun.

Ich habe versucht, diese Frage vorher sowohl von Gleichaltrigen, als auch online zu stellen, aber ich habe nie eine sehr befriedigende Antwort gehört. ... Oh warte .. Was war die Frage?

Wie kombinieren Sie testgetriebene Entwicklung mit einem Design, das sich ändern muss, um ein wachsendes Verständnis für den Problemraum zu reflektieren? Wie lässt sich die TDD-Praxis für Sie anstatt gegen Sie arbeiten?

Aktualisierung: Ich glaube immer noch nicht, dass ich alles vollständig verstehe, also kann ich nicht wirklich entscheiden, welche Antwort ich annehmen soll. Die meisten meiner Sprünge sind in den Kommentaren passiert, nicht in den Antworten. Hier ist eine Sammlung meiner Favoriten:

  

"Wer Begriffe wie" risikofrei "verwendet   In der Softwareentwicklung ist es in der Tat voll   Scheiße. Aber schreibe TDD nicht einfach ab   weil einige seiner Befürworter sind   Hyper-anfällig für Hype. ich finde es   hilft mir, mein Denken vorher zu klären   einen Code zu schreiben, hilft mir dabei   reproduzieren Fehler und beheben sie und macht   Ich bin selbstsicherer beim Refactoring   Dinge, wenn sie anfangen, hässlich auszusehen "

-Kristopher Johnson

  

"In diesem Fall schreiben Sie die Tests um   nur für die Teile der Schnittstelle   das hat sich geändert und bedenkt   Du hast Glück, einen guten Test zu haben   Berichterstattung an anderer Stelle, die Ihnen sagen wird   welche anderen Objekte hängen davon ab. "

-rcoder

  

"In TDD, der Grund, die Tests zu schreiben   ist Design zu machen. Der Grund zu machen   Die Tests automatisiert ist so, dass Sie können   Verwende sie als Design und Code   entwickeln. Wenn ein Test bricht, bedeutet es   du hast irgendwie früher verletzt   Designentscheidung. Vielleicht ist das ein   Entscheidung, die Sie ändern möchten, aber es ist   gut, um dieses Feedback zu bekommen, sobald   möglich. "

-Kristopher Johnson

  

[über Testschnittstellen] "Ein Test würde einige Elemente einfügen,   überprüfen Sie, dass die Größe der entspricht   Anzahl der eingefügten Elemente, überprüfen   Das contains () gibt für sie true zurück   aber nicht für Dinge, die nicht waren   eingefügt, prüft, ob remove () funktioniert,   usw. Alle diese Tests wären   identisch für alle Implementierungen und   natürlich würden Sie den gleichen Code ausführen   für jede Implementierung und nicht kopieren   es. Wenn sich die Schnittstelle ändert,   Sie müssten nur den Test anpassen   Code einmal, nicht einmal für jeden   Implementierung. "

-Michael Borgwardt

    
Breton 31.08.2009, 23:28
quelle

9 Antworten

3

Eine der Praktiken von TDD ist die Verwendung von Baby Steps (was am Anfang sehr langweilig sein könnte), das ist die Verwendung von wirklich kleinen Schritten, damit Sie Ihren Problemraum verstehen und eine gute und befriedigende Lösung dafür finden dein Problem.

Wenn Sie das Design Ihrer Anwendung bereits kennen, machen Sie TDD überhaupt nicht. Wir sollten es während Ihrer Tests entwerfen.

Der Vorschlag, den ich Ihnen geben würde, ist, dass Sie sich auf die Babyschritte konzentrieren, um ein richtiges testbares Design zu bekommen

    
Diego Dias 31.08.2009 23:42
quelle
1

Ich glaube nicht, dass ein echter TDD-Praktizierender behaupten wird, dass er die Möglichkeit von Fehlern oder Rückschritten vollständig eliminiert.

Denken Sie daran, dass es bei TDD grundsätzlich um Design geht, nicht um Testing oder Qualitätskontrolle. "Alle meine Tests bestehen" bedeutet nicht "Ich bin fertig".

Wenn sich Ihre Anforderungen oder das Design auf hohem Niveau drastisch ändern, müssen Sie möglicherweise alle Ihre Tests zusammen mit dem gesamten Code wegwerfen. So sind die Dinge manchmal. Es bedeutet nicht, dass TDD Ihnen nicht hilft.

    
Kristopher Johnson 31.08.2009 23:45
quelle
1

Richtig angewendet sollte TDD Ihr Leben angesichts der sich ändernden Anforderungen tatsächlich viel einfacher machen.

Meiner Erfahrung nach ist Code, der leicht zu testen ist, Code, der von anderen Subsystemen orthogonal ist und der klar definierte Schnittstellen hat. Angesichts eines solchen Ausgangspunkts ist es viel einfacher, wichtige Teile Ihrer Anwendung neu zu schreiben, da Sie mit der Gewissheit arbeiten können, dass a) Ihre Änderungen auf einige Subsysteme isoliert sind und b) Brüche schnell als fehlgeschlagene Tests auftreten .

Wenn Sie dagegen nach der Entwicklung nur Komponententests an Ihrem Code durchführen, treten möglicherweise Probleme auf, wenn sich die Anforderungen ändern. Es gibt einen Unterschied zwischen Tests, die schnell ausfallen, wenn Subsysteme sich ändern (weil sie Regressionen effektiv kennzeichnen), und solchen, die brüchig sind, weil sie von zu vielen nicht zusammenhängenden Teilen des Systemzustands abhängen. Ersteres sollte durch ein paar Codezeilen reparierbar sein, während letzteres dazu führen kann, dass Sie sich stundenlang am Kopf kratzen und versuchen, sie zu entwirren.

    
rcoder 31.08.2009 23:48
quelle
1

Die einzig wahre Antwort ist es kommt darauf an .

  • Es gibt Möglichkeiten, TDD falsch zu machen, wie z dass es nicht in dein passt Umwelt und isst Anstrengung mit minimaler Vorteil.
  • Es gibt Möglichkeiten, TDD richtig zu machen, wie z dass es sowohl Kosten senkt als auch steigt Qualität.
  • Es gibt Wege zu etwas ähnlich - aber anders als TDD, die kann oder kann nicht TDD genannt werden, und kann oder kann nicht angemessener sein Ihre besondere Situation.

Es ist eine seltsame Eigenart des Marktes für Software-Tools und Experten, die, um den Umsatz für diejenigen, die sie vorantreiben, zu maximieren, immer so geschrieben werden, als würden sie sich irgendwie auf "alle Software" beziehen.

Wahrheit ist, Software ist so unterschiedlich wie Hardware, und niemand würde daran denken, ein Buch über Brückenbau zu kaufen, um ein elektronisches Gerät zu entwerfen oder einen Gartenschuppen zu bauen.

    
soru 01.09.2009 00:06
quelle
1

Ich denke, Sie haben einige Missverständnisse über TDD. Für eine gute Erklärung und ein Beispiel dessen, was es ist und wie man es benutzt, empfehle ich Kent Becks Testgetriebene Entwicklung: Mit Beispiel .

Hier sind ein paar weitere Kommentare, die Ihnen helfen können zu verstehen, was TDD ist und warum einige Leute darauf schwören:

"Wie kombinieren Sie testgetriebene Entwicklung mit einem Design, das sich ändern muss, um ein wachsendes Verständnis für den Problemraum zu reflektieren?"

  • TDD ist eine Technik, um einen Problemraum zu erforschen und ein Design zu entwickeln und zu entwickeln, das Ihren Bedürfnissen entspricht. TDD ist nicht etwas, was du zusätzlich zum Design machst; it macht Design.

"Wie funktioniert die TDD-Praxis für Sie anstatt gegen Sie?"

  • TDD ist nicht "doppelt so viel Arbeit" wie TDD nicht. Ja, Sie werden eine Menge Tests schreiben, aber das braucht nicht wirklich viel Zeit und die Mühe ist nicht verschwendet. Du musst deinen Code irgendwie testen, oder? Das Ausführen automatisierter Tests ist viel schneller als das manuelle Testen, wenn Sie etwas ändern.

  • Viele TDD Tutorials zeigen sehr detaillierte Tests jeder Methode jeder Klasse. Im wirklichen Leben tun die Leute das nicht. Es ist dumm, einen Test für jeden Setter, jeden Getter und so weiter zu schreiben. Das Beck-Buch zeigt sehr gut, wie man TDD verwendet, um schnell etwas zu entwerfen und zu implementieren, und verlangsamt sich auf "kleine Schritte", wenn es schwierig wird. Siehe Wie tief sind Ihre Unit-Tests , um mehr zu diesem Punkt zu erfahren.

  • Bei TDD geht es nicht um Regressionstests. Bei TDD geht es darum zu denken, bevor Sie Code schreiben. Aber Regressionstests sind ein netter Nebeneffekt. Sie garantieren nicht, dass Code nie kaputt geht, aber sie helfen sehr.

  • Wenn Sie Änderungen vornehmen, die dazu führen, dass Tests abgebrochen werden, ist das keine schlechte Sache. es ist wertvolles Feedback. Designs ändern sich und Ihre Tests sind nicht in Stein gemeißelt. Wenn sich Ihr Design so geändert hat, dass einige Tests nicht mehr gültig sind, werfen Sie sie einfach weg. Schreiben Sie die neuen Tests, die Sie für das neue Design benötigen.

Kristopher Johnson 01.09.2009 11:06
quelle
0
  

es ist nicht länger eine einfache Sache von   Eintauchen und "den Käfer" reparieren, aber   Sie müssen auch alle neu schreiben   Tests.

Ein Grundgedanke von TDD ist die Vermeidung von Doppelungen sowohl im Produktionscode als auch im Testcode. Wenn eine einzelne Designänderung bedeutet, dass Sie alles neu schreiben müssen, haben Sie TDD nicht gemacht (oder es überhaupt nicht richtig gemacht).

Idealerweise sind Designänderungen in einem gut konzipierten System mit ordnungsgemäßer Trennung der Belange lokal, genau wie Implementierungsänderungen. Während die reale Welt selten ideal ist, bekommen Sie normalerweise etwas dazwischen: Sie müssen einige des Produktionscodes und einige der Tests ändern, aber nicht alles, und die Änderungen sind meist einfach und möglicherweise sogar automatisch durch Refactoring-Tools durchgeführt werden.

    
Michael Borgwardt 31.08.2009 23:39
quelle
0

Kodieren Sie etwas, ohne zu wissen, was am besten in der Benutzeroberfläche funktioniert, während Sie gleichzeitig Unitests schreiben. Das ist sehr zeitaufwendig. Es ist besser, mit einigen Prototypen der GUI zu beginnen, um die Interaktion richtig zu machen ... und dann mit Unitests neu zu schreiben (wenn der Arbeitgeber es erlaubt).

    
neoneye 31.08.2009 23:59
quelle
0

Kontinuierliche Integration (CI) ist ein Schlüssel. Wenn Ihre Tests automatisch jedes Mal ausgeführt werden, wenn Sie in die Quellcodeverwaltung einchecken (und alle anderen sehen sie, wenn sie fehlschlagen), ist es einfacher, "veraltete" Tests zu vermeiden und im grünen Bereich zu bleiben.

Wie Herr Dias erwähnt hat, sind Baby Steps wichtig. Sie machen ein kleines Refactoring, Sie führen Ihre Tests durch. Wenn Tests abgebrochen werden, bestimmen Sie sofort, ob dies erwartet wird (Designänderung) oder ein fehlgeschlagenes Refactoring. Wenn Tests wirklich unabhängig sind (kommt mit der Praxis), ist dies selten sehr schwierig. Entwickeln Sie Ihr Design langsam.

Siehe auch Ссылка - und kaufen Sie das Buch auf jeden Fall !

EDIT: Vielleicht sehe ich das falsch an. Angenommen, Sie hatten eine ältere Codebase, die Sie neu gestalten wollten. Das erste, was ich versuchen würde, ist Tests für das aktuelle Verhalten hinzuzufügen. Refactoring ohne Tests ist riskant - Sie könnten das Verhalten ändern. Danach begann ich, das Design in kleinen Schritten zu bereinigen und nach jedem Schritt meine Komponententests auszuführen. Das würde mir Sicherheit geben, dass meine Änderungen nichts kaputt machen würden.

Irgendwann könnte sich die API ändern. Dies wäre eine bahnbrechende Änderung - Clients müssten aktualisiert werden. Die Tests würden mir das sagen - was gut ist, weil ich alle bestehenden Clients (einschließlich der Tests) aktualisieren müsste.

Das ist jetzt nicht TDD. Aber die Idee ist die gleiche - die Tests sind Verhaltensspezifikationen (ja, ich bin in BDD shading), und sie geben mir das Vertrauen, um die Umsetzung zu refaktorieren, während ich sicherstelle, dass ich das Verhalten behalte (und mich darüber informiert, wenn ich ändere die Schnittstelle).

In der Praxis habe ich festgestellt, dass TDD mir unmittelbar Rückmeldung über ein schlechtes Interface-Design gibt. Ich bin mein erster Kunde - ich weiß, wann meine API schwer zu verwenden ist.

    
TrueWill 31.08.2009 23:49
quelle
0

Wir neigen dazu, mit TDD viel weniger zu entwerfen, da wir wissen, dass es sich ändern kann. Ich habe Projekte durch riesige Kreisläufe (es ist eine Web-App, nein, es ist ein RESTful Server, nein, es ist ein Bot). Die Tests geben mir die Möglichkeit, Ihren Code viel einfacher zu refaktorieren und neu zu strukturieren und weiterzuentwickeln als bisher nicht getesteter Code. Obwohl es widersprüchlich scheint, ist es wahr - obwohl Sie mehr Code haben, sind Sie in der Lage, größere Änderungen vorzunehmen und Vertrauen zu haben, dass in der vorhandenen Funktionalität nichts gebrochen wurde.

Ich verstehe Ihre Bedenken, dass grundlegende Annahmen Sie dazu bringen, Tests zu verwerfen. Das scheint intuitiv, aber ich persönlich habe es nicht gesehen. Einige Tests gehen, aber die meisten sind noch gültig - oft ist eine größere Veränderung nicht so groß wie es zunächst scheint. Außerdem, wenn Sie Tests besser schreiben, neigen Sie dazu, weniger spröde zu schreiben, was hilft.

    
ndp 02.09.2009 05:33
quelle

Tags und Links