4 Stimmen

Ist TDD ein Top-Bottom- oder Bottom-Top-Design?

In meiner Erinnerung sagten mir die meisten Leute, ich solle von oben nach unten entwerfen. Wenn ich eine Webseite implementieren möchte, sollte ich diese Seite auf dem Papier abbilden oder zeichnen und sie dann in einige Funktionen unterteilen. Für jede Funktionalität versuche ich, die externe API zu entwerfen und sie entsprechend zu implementieren.

Aber in TDD heißt es, ich solle zuerst eine sehr kleine Funktionalität (eine Methode?) betrachten, ihren Test schreiben, fehlschlagen, sie implementieren und den Test bestehen. Das Zusammensetzen ist der letzte Schritt. Ich kann mir nicht vorstellen, wie es gute API bekommt.

Und am merkwürdigsten ist, dass sie sagen, TDD sei nicht nur Unit-Tests und auch Funktionstests. Ich denke, es bedeutet oben-unten. Wenn es eine Funktionalität A gibt, die aus den Methoden B, C und D besteht, dann schreibe ich im Sinne von TDD zuerst den Funktionstest für A. Aber ... B, C, D sind alle unimplementiert. Sollte ich drei Stubs verwenden? Wenn B von den anderen drei Methoden abhängt?

Ich habe TDD verwendet, um einige kleine Programme zu schreiben. Aber als ich eine Anwendung mit GUI anstrebte, blieb ich stecken.

2voto

Da TDD mit dem beginnt, was man von außen sehen kann (von dem, woran man gerade arbeitet), bin ich nicht sicher, wie man es als Bottom-up bezeichnen kann.

Wenn man TDD auf die Spitze treibt (z. B. wie bei XP, auch bekannt als extreme Programmierung), würde man sicherlich aus der Perspektive des Endbenutzers beginnen und immer nur so viel Code schreiben, wie man braucht, um die bisher erstellten Tests zu bestehen. Wenn Sie mit den Tests für eine interne Funktion beginnen, bevor Sie den Punkt erreichen, an dem die übergeordneten Tests (und ein gutes Design für den Code, den Sie schreiben, um diese Tests zu bestehen) diese Routine erfordern, arbeiten Sie nach einem anderen Paradigma und nicht nach strengem TDD - denn es gab keinen Test, der Ihnen sagte, dass Sie diese Methode überhaupt schreiben sollten. Nicht, dass dies unbedingt eine schlechte Sache ist, aber alle Probleme, die Sie damit haben, ist nicht wirklich eine der TDD-Methodik.

Bei der GUI-Programmierung haben Sie natürlich das Standardproblem, Tests zu automatisieren, noch bevor Sie Code erstellt haben. Ich kenne dafür nur gute Tools für Webanwendungen; wenn Sie gute Tipps zu diesem Thema für den Desktop-Bereich haben, würde ich sie gerne sehen.

0voto

Spyros Punkte 44082

Ich habe stark schreiben rspec Tests für meine Schienen-Projekte halten ein Verhältnis von etwa 1:1,6 zwischen Code/Tests. Ich hatte nie wirklich ein Problem, was zuerst zu schreiben oder was es hängt von. Wenn die Methode A, die ich schreiben möchte, aus B und C besteht, dann würde ich zuerst B und C implementieren, wiederum unter Verwendung der richtigen Tests. Für mich ist die Reihenfolge nicht so wichtig, solange die Tests gut und präzise sind.

Ich verwende Stubs also nicht wirklich so, wie Sie es beschreiben, sondern nur, wenn die Funktionalität bereits vorhanden ist und ich sie nur umgehen möchte.

Übrigens gilt dies als Top-Down-Ansatz. Dies ist ein Auszug aus dem Rspec-Buch:

Wenn Sie erfahrene Software Softwareentwickler fragen, warum sie ein Projekt ein Projekt auf diese Weise durchführen, indem sie es Planung und Analyse, um dann in den detaillierten Entwurf und die und programmieren und es erst am Ende wirklich integrieren und testen, werden sie werden sie in die Ferne blicken, älter älter als ihre Jahre, und erklären geduldig erklären, dass dies zur Entschärfung gegen die exponentiellen Kosten der Kosten der Veränderung - das Prinzip, dass die Einführung eine Änderung oder die Entdeckung eines Fehlers exponentiell teurer wird je später man ihn entdeckt. Die Website Top-Down-Ansatz scheint die einzige sinnvoller Weg zur Absicherung gegen die Möglichkeit der Entdeckung eines Fehlers spät am Tag zu entdecken.

0voto

bcarlso Punkte 2305

Ich würde sagen, es ist von oben nach unten. Angenommen, ich hätte eine einzige PDF-Datei mit vier verschiedenen Dokumenten und würde eine Software schreiben, um sie in vier einzelne Dokumente aufzuteilen, anstatt in ein einziges Dokument, dann würde ich wahrscheinlich als erstes einen Test schreiben:

// Note: Keeping this very abstract
@Test
public void splitsDocumentsAccordingToDocumentType() {
   List docs = new DocumentProcessor().split(new SinglePdfWithFourDocs());
   assertEquals(4, docs());
   ...
}

Ich würde die DocumentProcessor.split() Methode ähnlich wie "A" in Ihrem Beispiel zu sein. Ich könnte nun den gesamten Algorithmus in einer einzigen Methode implementieren split und die Tests zu bestehen. Ich brauche nicht einmal "B" oder "C", richtig? Da Sie ein guter Entwickler sind und Ihnen bei dem Gedanken an diese 1500-Zeilen-Methode übel wird, suchen Sie nach Möglichkeiten, Ihren Code so umzustrukturieren, dass er besser geeignet ist. Vielleicht sehen Sie, dass zwei zusätzliche Objekte (Verantwortlichkeiten) aus diesem Code herausgelöst werden könnten:

1) Parsen des Dateiinhalts, um die einzelnen Dokumente zu finden und 2) Lesen und Schreiben des Dokuments aus dem Dateisystem

Fangen wir mit der Nummer 1 an. Verwenden Sie ein paar "Extract Method"-Refactorings, um Code zu lokalisieren, der mit dem Parsen des Inhalts zusammenhängt, und dann ein "Extract Class"-Refactoring, das diese Methoden in eine Klasse mit dem Namen, sagen wir DocumentParser . Dies könnte mit "B" in Ihrem Beispiel vergleichbar sein. Wenn Sie möchten, können Sie die Tests, die sich auf das Parsen von Dokumenten beziehen, von Ihrem DocumentProcessorTest zu einer neuen DocumentParserTest und verhöhnen oder streichen die DocumentParser im DocumentProcessorTest .

Bei Nr. 2 heißt es schäumen, spülen, wiederholen, und am Ende hat man so etwas wie einen DocumentSerializer Klasse, alias "C". Sie können dies auch in Ihrer DocumentProcessorTest und Sie haben jetzt keine Datei-E/A mehr und haben eine Komponente getestet, die zwei zusätzliche Mitarbeiter hat, ohne Ihre gesamte Klasse (mit einzelnen Methoden) entwerfen zu müssen. Beachten Sie, dass wir einen "Outside-in"-Ansatz gewählt haben, der das Refactoring wirklich ermöglicht.

Danke

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X