Ich verstehe nicht, wie TDD mir hilft, ein gutes Design zu erhalten, wenn ich ein Design benötige, um es zu testen


50

Ich versuche, mich mit TDD zu beschäftigen, insbesondere mit dem Entwicklungsteil. Ich habe mir einige Bücher angesehen, aber die, die ich gefunden habe, befassen sich hauptsächlich mit dem Testteil - der Geschichte von NUnit, warum das Testen gut ist, Rot / Grün / Refaktor und wie man einen Zeichenkettenrechner erstellt.

Gutes Zeug, aber das ist "nur" Unit Testing, nicht TDD. Insbesondere verstehe ich nicht, wie TDD mir hilft, ein gutes Design zu erhalten, wenn ich ein Design benötige, um es zu testen.

Stellen Sie sich zur Veranschaulichung diese drei Anforderungen vor:

  • Ein Katalog muss eine Produktliste enthalten
  • Der Katalog sollte sich merken, welche Produkte ein Benutzer angesehen hat
  • Benutzer sollten in der Lage sein, nach einem Produkt zu suchen

An diesem Punkt ziehen viele Bücher ein magisches Kaninchen aus dem Hut und tauchen nur in "Testing the ProductService" ein, aber sie erklären nicht, wie sie zu dem Schluss gekommen sind, dass es überhaupt einen ProductService gibt. Das ist der "Entwicklungsteil" in TDD, den ich zu verstehen versuche.

Es muss ein vorhandenes Design geben, aber Dinge außerhalb von Entity-Services (das heißt: Es gibt ein Produkt, also sollte es einen ProductService geben) sind nirgends zu finden (z. B. erfordert die zweite Anforderung, dass ich ein Konzept von a habe Benutzer, aber wo sollte ich die Funktionen zur Erinnerung hinstellen? Und ist Suche eine Funktion des ProductService oder ein separater SearchService? Woher sollte ich wissen, welche ich wählen soll?)

Laut SOLID würde ich einen UserService benötigen, aber wenn ich ein System ohne TDD entwerfe, könnte es sein, dass ich eine ganze Reihe von Single-Method Services bekomme. Soll ich mit TDD nicht erst mein Design entdecken?

Ich bin ein .NET-Entwickler, aber Java-Ressourcen würden auch funktionieren. Ich habe das Gefühl, dass es anscheinend keine echte Beispielanwendung oder ein Buch gibt, die bzw. das sich mit einer echten Branchenanwendung befasst. Kann jemand ein klares Beispiel liefern, das den Prozess der Erstellung eines Designs mit TDD veranschaulicht?


2
TDD ist nur ein Teil der gesamten Entwicklungsmethodik. Natürlich müssen Sie eine Art Design (entweder im Vorfeld oder besser evolutionär) verwenden, um das Ganze zusammenzubringen.
Euphorisch

3
@gnat: Es geht um die Frage, warum die TDD-Bücher den Entwurfsprozess nicht klarer machen.
Robert Harvey

4
@gnat: Es war deine Bearbeitung, nicht meine. :) Siehe meine Änderung am Titel der Frage und den Körper.
Robert Harvey

9
Wenn Sie die Arbeit von Robert C. Martin gelesen oder sich vielleicht eines seiner Videos angesehen haben, werden Sie feststellen, dass er häufig ein Design im Sinn hat, aber nicht damit verheiratet ist. Er glaubt, dass seine vorgefertigte Vorstellung vom richtigen Design aus seinen Tests hervorgehen wird, aber er zwingt es nicht dazu. Und am Ende tut es manchmal dieses Design und manchmal nicht. Mein Punkt hier ist, dass Ihre eigenen vorherigen Erfahrungen Sie leiten, aber die Tests sollten Sie fahren. Tests sollten in der Lage sein, Ihr Design zu entwickeln oder zu entlarven.
Anthony Pegram

3
Es geht also nicht wirklich um Testen, sondern um Design. Es hilft Ihnen nur nicht wirklich beim Design, sondern vielmehr bei der Validierung des Designs. Aber ist das nicht! @ # $ Ing Testen?
Erik Reppen

Antworten:


17

Die Idee von TDD ist, mit dem Testen zu beginnen und daran zu arbeiten. Wenn Sie also ein Beispiel für "Ein Katalog muss eine Liste von Produkten enthalten" nehmen, bedeutet dies, dass der Test "Nach Produkten im Katalog suchen" lautet, und dies ist somit der erste Test. Was beinhaltet ein Katalog? Was beinhaltet ein Produkt? Dies sind die nächsten Teile, und die Idee ist, einige Teile zusammenzufügen, die so etwas wie ein ProductService sind, der entsteht, wenn dieser erste Test bestanden wird.

Die Idee von TDD ist, mit einem Test zu beginnen und dann den Code zu schreiben, der diesen Test als ersten Punkt bestehen lässt. Komponententests sind Teil dieses Ja, aber Sie sehen sich nicht das Gesamtbild an, das sich aus Tests und dem anschließenden Schreiben des Codes zusammensetzt, damit es an dieser Stelle keine blinden Flecken gibt, da noch kein Code vorhanden ist.


Test Driven Development Tutorial, in dem die Folien 20-22 die wichtigsten sind. Die Idee ist, zu wissen, was die Funktionalität als Ergebnis haben soll, einen Test dafür zu schreiben und dann eine Lösung zu erstellen. Das Designteil kann variieren, je nachdem, was erforderlich ist oder nicht. Ein wichtiger Punkt ist, TDD von Anfang an zu verwenden, anstatt zu versuchen, spät in ein Projekt einzuführen. Wenn Sie zuerst mit Tests beginnen, kann dies hilfreich sein und ist in gewissem Sinne erwähnenswert. Wenn Sie versuchen, die Tests später hinzuzufügen, wird dies möglicherweise verschoben oder verzögert. Die späteren Folien können ebenfalls nützlich sein.


Ein Hauptvorteil von TDD ist, dass Sie zu Beginn der Tests nicht an ein Design gebunden sind. Daher besteht die Idee darin, die Tests zu erstellen und den Code zu erstellen, der diese Tests als Entwicklungsmethode besteht. Ein Big Design Up Front kann zu Problemen führen, da dadurch die Idee entsteht, Dinge zu verriegeln, wodurch das System letztendlich weniger flink gebaut wird.


Robert Harvey fügte dies in den Kommentaren hinzu, die es wert sind, in der Antwort erwähnt zu werden:

Leider denke ich, dass dies ein verbreiteter Irrtum in Bezug auf TDD ist: Sie können eine Softwarearchitektur nicht erweitern, indem Sie nur Komponententests schreiben und diese bestehen lassen. Das Schreiben von Komponententests hat zwar Einfluss auf das Design, erstellt das Design jedoch nicht . Das musst du tun.


31
@MichaelStum: Leider denke ich, dass dies ein verbreiteter Irrtum in Bezug auf TDD ist: Sie können eine Softwarearchitektur nicht erweitern, indem Sie nur Komponententests schreiben und diese bestehen lassen. Das Schreiben von Komponententests hat zwar Einfluss auf das Design, erstellt das Design jedoch nicht . Das musst du machen.
Robert Harvey

4
@RobertHarvey, JimmyHoffa: Wenn ich Ihre Kommentare 100 Mal abstimmen könnte, würde ich!
Doc Brown

9
@Robert Harvey: Ich bin froh, dass Sie über dieses häufige Missverständnis geschrieben haben: Ich höre viel zu oft, dass man sich einfach hinsetzen und alle Arten von Komponententests schreiben muss und ein Design einfach spontan "auftaucht". Und wenn Ihr Design schlecht ist, liegt es daran, dass Sie nicht genügend Komponententests geschrieben haben. Ich stimme Ihnen zu, dass Tests ein Werkzeug sind, um Anforderungen für Ihr Design zu spezifizieren und zu verifizieren, aber "Sie müssen das Design selbst machen". Ich bin völlig einverstanden.
Giorgio

4
@ Giorgo, RobertHarvey: +1000 an RobertHarvey auch von mir. Leider ist dieses Missverständnis so weit verbreitet, dass einige "erfahrene" TDD / Agile-Praktiker glauben, dass es wahr ist. So tun sie beispielsweise so, als könnten Sie einen Sudoku-Löser aus TDD heraus "entwickeln", ohne dass Domain-Kenntnisse oder Analysen erforderlich sind . Ich frage mich, ob Ron Jeffries jemals ein Follow-up zu den Einschränkungen von TDD veröffentlicht oder erklärt hat, warum er sein Experiment plötzlich abgebrochen hat, ohne dass Schlussfolgerungen gezogen oder Lehren gezogen wurden.
Andres F.

3
@Andres F: Ich kenne die Geschichte über Sudoku und finde sie sehr interessant. Ich denke, einige Entwickler machen den Fehler zu glauben, dass ein Tool (z. B. TDD oder SCRUM) Domänenwissen und ihre eigenen Anstrengungen ersetzen kann, und erwarten, dass durch die mechanische Anwendung einer bestimmten Methode eine gute Software auf magische Weise "entstehen" wird. Es sind oft Leute, die nicht gerne zu viel Zeit mit Analyse und Design verbringen und es vorziehen, etwas direkt zu codieren. Für sie ist das Befolgen einer bestimmten Methodik ein Alibi, um nicht richtig zu entwerfen. Aber dies ist meiner Meinung nach ein Missbrauch von TDD.
Giorgio

8

TDD hilft mir, schneller zum besten Design zu kommen, als TDD nicht. Ich würde wahrscheinlich mit oder ohne zum besten Design kommen. Aber die Zeit, die ich damit verbracht hätte, darüber nachzudenken und ein paar Male in den Code einzutauchen, wird stattdessen damit verbracht, Tests zu schreiben. Und es ist weniger Zeit. Für mich. Nicht für jeden. Und selbst wenn es genauso lange dauern würde, würde ich eine Reihe von Tests durchführen müssen, damit das Refactoring sicherer und der Code auf der ganzen Linie noch besser wird.

Wie macht es das?

Erstens ermutigt es mich, über jede Klasse als Dienst für einen Clientcode nachzudenken. Besserer Code entsteht, wenn man sich überlegt, wie der aufrufende Code die API verwenden soll, anstatt sich Gedanken darüber zu machen, wie der Code selbst aussehen soll.

Zweitens hindert es mich daran, viel zu viel zyklometische Komplexität in eine Methode zu schreiben, während ich darüber nachdenke. Jeder zusätzliche Weg durch eine Methode wird dazu neigen, die Anzahl der Tests, die ich durchführen muss, zu verdoppeln. Bloße Faulheit diktiert, dass, nachdem ich zu viel Logik hinzugefügt habe und 16 Tests schreiben muss, um eine Bedingung hinzuzufügen, es Zeit ist, einige davon in eine andere Methode / Klasse zu ziehen und sie separat zu testen.

Es ist wirklich so einfach. Es ist kein magisches Designwerkzeug.


6

Ich versuche, TDD in den Kopf zu stecken ... Stellen Sie sich zur Veranschaulichung die folgenden drei Anforderungen vor:

  • Ein Katalog muss eine Produktliste enthalten
  • Der Katalog sollte sich merken, welche Produkte ein Benutzer angesehen hat

Diese Anforderungen sollten in menschlicher Hinsicht angepasst werden. Wer möchte wissen, welche Produkte der Benutzer zuvor angesehen hat? Der Benutzer? Ein Verkäufer?

  • Benutzer sollten in der Lage sein, nach einem Produkt zu suchen

Wie? Namentlich? Nach Marke? Der erste Schritt in der testgetriebenen Entwicklung besteht darin, einen Test zu definieren, zum Beispiel:

browse to http://ourcompany.com
enter "cookie" in the product search box
page should show "chocolate-chip cookies" and "oatmeal cookies"

>

An diesem Punkt ziehen viele Bücher ein magisches Kaninchen aus dem Hut und tauchen nur in "Testing the ProductService" ein, aber sie erklären nicht, wie sie zu dem Schluss gekommen sind, dass es überhaupt einen ProductService gibt.

Wenn dies die einzigen Voraussetzungen sind, würde ich auf keinen Fall einen Produktservice erstellen. Ich könnte eine sehr einfache Webseite mit einer statischen Produktliste erstellen. Das würde perfekt funktionieren, bis Sie die Anforderungen zum Hinzufügen und Löschen von Produkten erfüllen. An diesem Punkt könnte ich entscheiden, dass es am einfachsten ist, eine relationale Datenbank und einen ORM zu verwenden und eine Produktklasse zu erstellen, die einer einzelnen Tabelle zugeordnet ist. Immer noch kein ProductService. Klassen wie ProductService werden erstellt, wenn und wenn sie benötigt werden. Möglicherweise müssen mehrere Webanforderungen dieselben Abfragen oder Aktualisierungen ausführen. Anschließend wird die ProductService-Klasse erstellt, um das Kopieren von Code zu verhindern.

Zusammenfassend lässt sich sagen, dass TDD den zu schreibenden Code steuert. Der Entwurf erfolgt, wenn Sie Implementierungsentscheidungen treffen und den Code dann in Klassen umgestalten, um Duplikationen zu vermeiden und Abhängigkeiten zu steuern. Wenn Sie Code hinzufügen, müssen Sie neue Klassen erstellen, um den Code SOLID beizubehalten. Sie müssen sich jedoch nicht im Voraus entscheiden, ob Sie eine Produktklasse und eine ProductService-Klasse benötigen. Sie können feststellen, dass das Leben mit nur einer Produktklasse vollkommen in Ordnung ist.


OK, nein ProductServicedann. Aber wie hat TDD Ihnen gesagt, dass Sie eine Datenbank und einen ORM benötigen?
Robert Harvey

4
@ Robert: hat es nicht. Es ist eine Designentscheidung, basierend auf meiner Einschätzung, wie die Anforderungen am effektivsten erfüllt werden können. Aber die Entscheidung könnte sich ändern.
Kevin Cline

1
Gutes Design wird niemals als Nebeneffekt eines willkürlichen Prozesses entstehen. Ein System oder Modell zu haben, mit dem man arbeiten und Dinge bearbeiten kann, ist großartig, aber Test-first-TDD, IMO, stößt auf einen Interessenkonflikt, indem es sich selbst als etwas verkauft, das garantiert, dass die Leute nicht unerwartet von den Nebenwirkungen des Bösen gebissen werden Code, der eigentlich nicht hätte passieren dürfen. Design erfordert Reflexion, Bewusstsein und Voraussicht. Sie lernen diese nicht, indem Sie die automatisch entdeckten Symptome vom Baum entfernen. Sie lernen sie, indem Sie herausfinden, wie Sie böse Mutantenzweige an erster Stelle vermeiden können.
Erik Reppen

Ich denke, der Test 'ein Produkt hinzufügen; Starten Sie den Computer neu und starten Sie das System neu. Das hinzugefügte Produkt sollte immer noch sichtbar sein. ' zeigt, woher der Bedarf an einer Art Datenbank kommt (aber das kann immer noch eine flache Datei oder XML sein).
Yatima2975

3

Andere mögen anderer Meinung sein, aber für mich basieren viele der neueren Methoden auf der Annahme, dass der Entwickler den größten Teil dessen tun wird, was die älteren Methoden aus Gewohnheit oder persönlichem Stolz formuliert haben für sie, und die Arbeit ist in einer sauberen Sprache oder die saubereren Teile einer etwas chaotischen Sprache gekapselt, so dass Sie alle Testgeschäfte erledigen können.

Einige Beispiele, bei denen ich in der Vergangenheit darauf gestoßen bin:

  • Nehmen Sie ein paar Spezialunternehmen und sagen Sie ihnen, dass ihr Team Agile und Test First ist. Sie haben oft keine andere Angewohnheit, als nach Vorgabe zu arbeiten, und sie kümmern sich nicht um die Qualität der Arbeit, solange diese lange genug dauert, um das Projekt abzuschließen.

  • Versuchen Sie, zuerst einen neuen Test durchzuführen, und verbringen Sie einen Großteil Ihrer Zeit damit, Tests zu rippen, da Sie feststellen, dass verschiedene Ansätze und Schnittstellen Mist sind.

  • Codieren Sie etwas Niedriges und geben Sie entweder eine Ohrfeige wegen mangelnder Abdeckung oder schreiben Sie eine Reihe von Tests, die nicht viel wert sind, weil Sie das zugrunde liegende Verhalten, an das Sie gebunden sind, nicht verspotten können.

  • Jede Situation, in der Sie nicht genug über die zugrunde liegenden Mechanismen verfügen, um eine testbare Funktion hinzuzufügen, ohne zuerst eine Reihe von nicht testbaren Bits zu schreiben, z. B. ein Festplattensubsystem oder eine Kommunikationsschnittstelle auf TCP / IP-Ebene.

Wenn Sie TDD machen und es für Sie funktioniert, ist es gut für Sie, aber es gibt eine Menge Dinge (ganze Jobs oder Phasen eines Projekts), bei denen dies einfach keinen Mehrwert bringt.

Ihr Beispiel hört sich so an, als wären Sie noch nicht einmal mit einem Entwurf befasst. Entweder müssen Sie sich mit der Architektur befassen, oder Sie erstellen einen Prototyp. Meiner Meinung nach müssen Sie zuerst einiges davon durchstehen.


1

Ich bin überzeugt, dass TDD ein sehr wertvoller Ansatz für das detaillierte Design des Systems ist - dh die APIs und das Objektmodell. Um jedoch zu dem Punkt in einem Projekt zu gelangen, an dem Sie anfangen würden, TDD zu verwenden, müssen Sie das Gesamtbild des Entwurfs in gewisser Weise bereits modelliert haben und das Gesamtbild der Architektur in gewisser Weise bereits modelliert haben. @ user414076 paraphrasiert, dass Robert Martin eine Designidee hat, aber nicht damit verheiratet ist. Genau. Fazit - TDD ist nicht die einzige Designaktivität, sondern die Art und Weise, wie die Details des Designs präzisiert werden. TDD müssen andere Entwurfsaktivitäten vorausgehen und zu einem Gesamtansatz (wie Agile) passen, der angibt, wie der Gesamtentwurf erstellt und weiterentwickelt wird.

Zu Ihrer Information - zwei Bücher, die ich zu diesem Thema empfehle und die konkrete und realistische Beispiele geben:

Wachsende objektorientierte Software, geführt von Tests - erklärt und gibt ein vollständiges Projektbeispiel. Dies ist ein Buch über Design, nicht Testen . Das Testen wird verwendet, um das erwartete Verhalten während der Entwurfsaktivitäten zu spezifizieren.

Testgetriebene Entwicklung Ein praktischer Leitfaden - eine langsame und schrittweise Anleitung zur Entwicklung einer vollständigen, wenn auch kleinen App.


0

TTD treibt die Designentdeckung durch Testfehler an, nicht durch Erfolg. Daher können Sie Unbekannte testen und iterativ erneut testen, da Unbekannte letztendlich einer vollständigen Reihe von Komponententests ausgesetzt sind - eine sehr schöne Sache für die laufende Wartung und eine sehr schwierige Sache, die Sie ausprobieren können Nachrüstung nach dem Schreiben / Freigeben des Codes.

Beispielsweise kann eine Anforderung sein, dass die Eingabe in verschiedenen Formaten erfolgen kann, von denen noch nicht alle bekannt sind. Mit TDD würden Sie zuerst einen Test schreiben, der sicherstellt, dass die entsprechende Ausgabe bei jedem Eingabeformat bereitgestellt wird . Offensichtlich schlägt dieser Test fehl. Schreiben Sie Code, um die bekannten Formate zu verarbeiten, und wiederholen Sie den Test. Da die unbekannten Formate durch das Sammeln von Anforderungen verfügbar gemacht werden, werden neue Tests geschrieben, bevor der Code geschrieben wird. Diese sollten ebenfalls fehlschlagen. Dann wird neuer Code geschrieben, um die neuen Formate zu unterstützen, und alle Tests werden wiederholt, um die Wahrscheinlichkeit einer Regression zu verringern.

Es ist auch hilfreich, sich einen Geräteausfall als "unvollendeten" Code anstelle eines "kaputten" Codes vorzustellen. TDD ermöglicht unfertige Einheiten (erwartete Ausfälle), verringert jedoch das Auftreten von defekten Einheiten (unerwartete Ausfälle).


1
Ich stimme zu, dass dies ein gültiger Workflow ist, aber er erklärt nicht wirklich, wie aus einem solchen Workflow eine übergeordnete Architektur entstehen kann.
Robert Harvey

1
Richtig, eine übergeordnete Architektur wie das MVC-Muster wird nicht allein aus TDD hervorgehen. Aus TDD kann jedoch Code hervorgehen, der auf einfache Weise testbar ist.
Daniel Pereira

0

In der Frage heißt es:

... viele Bücher ziehen ein magisches Kaninchen aus dem Hut und tauchen nur in "Testing the ProductService" ein, aber sie erklären nicht, wie sie zu dem Schluss gekommen sind, dass es überhaupt einen ProductService gibt.

Sie kamen zu diesem Schluss, indem sie darüber nachdachten, wie sie dieses Produkt testen würden. "Was für ein Produkt macht das?" "Nun, wir könnten einen Dienst schaffen". "Ok, lass uns einen Test für einen solchen Service schreiben"


0

Eine Funktionalität kann viele Designs haben und TDD sagt Ihnen nicht vollständig, welche die beste ist. Selbst wenn Sie durch Tests modulareren Code erstellen können, können Sie auch Module erstellen, die den Testanforderungen und nicht der Realität in der Produktion entsprechen. Sie müssen also verstehen, wohin Sie gehen und wie die Dinge in das Gesamtbild passen sollten. Anders ausgedrückt, es gibt funktionale und nicht funktionale Anforderungen. Vergessen Sie nicht die letzte.

Bezüglich des Designs verweise ich auf Bücher von Robert C. Martin (Agile Development), aber auch auf Martin Fowlers Patterns of Enterprise Application Architecture und Domain Driver Design. Letzteres ist besonders dann sehr systematisch, wenn es darum geht, die Entitäten und Beziehungen aus den Anforderungen zu extrahieren.

Wenn Sie dann ein gutes Gefühl für die verfügbaren Optionen zur Verwaltung dieser Entitäten haben, können Sie Ihren TDD-Ansatz unterstützen.


0

Soll ich mit TDD nicht erst mein Design entdecken?

Nein.

Wie können Sie etwas testen, das Sie nicht zuerst entworfen haben?

Stellen Sie sich zur Veranschaulichung diese drei Anforderungen vor:

  • Ein Katalog muss eine Produktliste enthalten
  • Der Katalog sollte sich merken, welche Produkte ein Benutzer angesehen hat
  • Benutzer sollten in der Lage sein, nach einem Produkt zu suchen

Dies sind keine Anforderungen, dies sind Definitionen von Daten. Ich weiß nicht, was das Geschäft mit Ihrer Software ist, aber es ist unwahrscheinlich, dass Analysten so sprechen.

Sie müssen wissen, was die Invarianten Ihres Systems sind.

Eine Anforderung wäre etwa:

  • Ein Kunde kann eine bestimmte Menge Produkt bestellen, wenn es genug von diesem Produkt auf Lager gibt.

Wenn dies die einzige Voraussetzung ist, haben Sie möglicherweise eine Klasse wie:

public class Product {

  private int quantity;

  public Product(int initialQuantity) {
    this.quantity = initialQuantity;
  }

  public void order(int quantity) {
    // To be implemented.
  }

}

Dann würden Sie mit TDD einen Testfall schreiben, bevor Sie die order () -Methode implementieren.

public void ProductTest() {

    public void testCorrectOrder() {

        Product p = new Product(10);
        p.order(3);
        p.order(4);

    }

    @Expect(ProductOutOfStockException)
    public void testIncorrectOrder() {

        Product p = new Product(10);
        p.order(7);
        p.order(4);

    }

}

Wenn der zweite Test fehlschlägt, können Sie die order () -Methode wie gewünscht implementieren.


0

Sie sind ganz richtig. TDD führt zu einer guten Implementierung eines bestimmten Designs. Es wird Ihrem Designprozess nicht helfen.


Es gibt Ihnen jedoch das Sicherheitsnetz, um das Design zu verbessern, ohne den Arbeitscode zu verletzen. Dies ist das Refactoring, das die meisten Leute überspringen.
Adrian Schneider

-3

TDD hilft viel, jedoch spielt die Softwareentwicklung eine wichtige Rolle. Der Entwickler sollte sich den Code anhören, der gerade geschrieben wird. Refactoring ist der dritte Teil des TDD-Zyklus. Dies ist der Hauptschritt, bei dem sich der Entwickler konzentrieren und überlegen sollte, bevor er zum nächsten roten Test übergeht. Gibt es eine Vervielfältigung? Werden SOLID-Prinzipien angewendet? Was ist mit hoher Kohäsion und geringer Kopplung? Was ist mit Namen? Schauen Sie sich den Code, der aus den Tests hervorgeht, genauer an und prüfen Sie, ob etwas geändert und neu gestaltet werden muss. Frage den Code und der Code sagt dir, wie er gestaltet werden soll. Normalerweise schreibe ich Sätze von mehreren Tests, untersuche diese Liste und erstelle ein einfaches Design. Es muss nicht "final" sein, normalerweise nicht, weil es sich ändert, wenn neue Tests hinzugefügt werden. Hier kommt das Design.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.