it-swarm.com.de

Ist es eine gute Idee, alle möglichen Testfälle zu schreiben, nachdem das Team auf TDD umgestellt wurde, um eine vollständige Abdeckung zu erreichen?

Angenommen, wir haben eine große Anwendung auf Unternehmensebene ohne Unit-/Funktionstests. Es gab keinen testgetriebenen Entwicklungsprozess während der Entwicklung aufgrund sehr enger Fristen (ich weiß, wir sollten niemals enge Fristen versprechen, wenn wir uns nicht sicher sind, aber was getan wird, wird getan!).

Nachdem alle Fristen abgelaufen waren und die Dinge ruhig waren, waren sich alle einig, uns in ein produktives TDD/BDD-basiertes Team zu verwandeln ... Yay!

Jetzt geht es um den Code, den wir bereits haben: (1) Ist es noch in Ordnung oder eine gute Idee, den größten Teil der Entwicklung zu stoppen und von Anfang an ganze mögliche Testfälle zu schreiben, obwohl (noch!) Alles in Ordnung ist? ? Oder (2) es ist besser, auf etwas Schlimmes zu warten und dann während des Fixes neue Komponententests zu schreiben, oder (3) sogar frühere Codes zu vergessen und nur Komponententests nur für die neuen Codes zu schreiben und alles auf den nächsten großen Refactor zu verschieben.

Es gibt einige gute und verwandte Artikel wie dieser . Ich bin mir immer noch nicht sicher, ob es sich lohnt, in dieses Projekt zu investieren, da wir nur eine sehr begrenzte Zeit haben und viele andere Projekte/Arbeiten auf uns warten.

Hinweis : Diese Frage erklärt/stellt sich eine völlig unangenehme Situation in einem Entwicklungsteam vor. Hier geht es nicht um mich oder einen meiner Kollegen; Es ist nur eine imaginäre Situation. Sie denken vielleicht, dass dies niemals passieren sollte oder der Entwicklungsmanager für ein solches Durcheinander verantwortlich ist! Aber was getan wird, wird getan. Wenn möglich, stimmen Sie nicht ab, nur weil Sie der Meinung sind, dass dies niemals passieren sollte.

17
Michel Gokan

Aufgrund der sehr engen Fristen gab es während der Entwicklung keinen testgetriebenen Entwicklungsprozess

Diese Aussage ist sehr besorgniserregend. Nicht, weil Sie ohne TDD entwickelt haben oder weil Sie nicht alles testen. Dies ist besorgniserregend, da es zeigt, dass Sie glauben, TDD würde Sie verlangsamen und Sie dazu bringen, eine Frist zu verpassen.

Solange Sie es so sehen, sind Sie nicht bereit für TDD. TDD ist nicht etwas, in das man sich allmählich hineinversetzen kann. Entweder wissen Sie, wie es geht, oder Sie wissen es nicht. Wenn Sie es auf halbem Weg versuchen, werden Sie es und sich selbst schlecht aussehen lassen.

TDD sollten Sie zuerst zu Hause üben. Lernen Sie es, denn es hilft Ihnen Code jetzt . Nicht, weil dir jemand gesagt hat, dass du es tun sollst. Nicht, weil es hilfreich ist, wenn Sie später Änderungen vornehmen. Wenn es etwas wird, was Sie tun , weil Sie es eilig haben, dann sind Sie bereit, es professionell zu tun.

TDD ist etwas, das Sie in jedem Shop tun können. Sie müssen nicht einmal Ihren Testcode abgeben. Sie können es für sich behalten, wenn die anderen Tests verachten. Wenn Sie es richtig machen, beschleunigen die Tests Ihre Entwicklung, auch wenn sie von niemand anderem ausgeführt werden.

Wenn andere Ihre Tests lieben und durchführen, sollten Sie dennoch bedenken, dass es selbst in einem TDD-Shop nicht Ihre Aufgabe ist, Tests einzuchecken. Es geht darum, bewährten funktionierenden Produktionscode zu erstellen. Wenn es testbar ist, ordentlich.

Wenn Sie der Meinung sind, dass das Management an TDD glauben muss oder dass Ihre Mitcodierer Ihre Tests unterstützen müssen, ignorieren Sie das Beste, was TDD für Sie tut. Es zeigt Ihnen schnell den Unterschied zwischen dem, was Ihr Code Ihrer Meinung nach tut, und dem, was er tatsächlich tut.

Wenn Sie nicht sehen können, wie dies allein dazu beitragen kann, eine Frist schneller einzuhalten, sind Sie bei der Arbeit nicht bereit für TDD. Sie müssen zu Hause üben.

Trotzdem ist es schön, wenn das Team Ihre Tests verwenden kann, um Ihren Produktionscode zu lesen, und wenn das Management schicke neue TDD-Tools kauft.

Ist es eine gute Idee, alle möglichen Testfälle zu schreiben, nachdem das Team auf TDD umgestellt wurde?

Unabhängig davon, was das Team tut, ist es nicht immer eine gute Idee, alle möglichen Testfälle zu schreiben. Schreiben Sie die nützlichsten Testfälle. Eine 100% ige Codeabdeckung ist kostenpflichtig. Ignorieren Sie nicht das Gesetz der sinkenden Rendite, nur weil es schwierig ist, ein Urteil zu fällen.

Sparen Sie Ihre Testenergie für die interessante Geschäftslogik. Das Zeug, das Entscheidungen trifft und Richtlinien durchsetzt. Testen Sie das verdammt noch mal. Langweiliger, einfach zu lesender struktureller Klebercode, der nur Dinge miteinander verbindet, muss nicht annähernd so schlecht getestet werden.

(1) Ist es noch in Ordnung oder eine gute Idee, den größten Teil der Entwicklung zu stoppen und von Anfang an ganze mögliche Testfälle zu schreiben, obwohl (noch!) Alles in Ordnung ist? Oder

Nein. Dies ist das Denken "Lass uns ein komplettes Umschreiben machen". Dies zerstört hart erarbeitetes Wissen. Bitten Sie das Management nicht um Zeit, um Tests zu schreiben. Schreiben Sie einfach Tests. Sobald Sie wissen, was Sie tun, werden Tests Sie nicht verlangsamen.

(2) Es ist besser, auf etwas Schlimmes zu warten und dann während des Fixes neue Komponententests zu schreiben, oder

(3) Vergessen Sie sogar frühere Codes und schreiben Sie nur Unit-Tests nur für die neuen Codes und verschieben Sie alles auf den nächsten großen Refactor.

Ich werde 2 und 3 auf die gleiche Weise beantworten. Wenn Sie den Code aus irgendeinem Grund ändern, ist es wirklich schön, wenn Sie einen Test bestehen können. Wenn der Code Legacy ist, wird derzeit kein Test begrüßt. Das heißt, es ist schwierig, es zu testen, bevor es geändert wird. Nun, da Sie es sowieso ändern, können Sie es in etwas Testbares ändern und es testen.

Das ist die nukleare Option. Es ist riskant. Sie nehmen Änderungen ohne Tests vor. Es gibt einige kreative Tricks, um Legacy-Code zu testen, bevor Sie ihn ändern. Sie suchen nach sogenannten Nähten, mit denen Sie das Verhalten Ihres Codes ändern können, ohne den Code zu ändern. Sie ändern Konfigurationsdateien, erstellen Dateien, was auch immer erforderlich ist.

Michael Feathers gab uns ein Buch darüber: Effektiv mit Legacy Code arbeiten. Lesen Sie es durch und Sie werden sehen, dass Sie nicht alles Alte niederbrennen müssen, um etwas Neues zu machen.

36
candied_orange

Ist es noch in Ordnung oder eine gute Idee, den größten Teil der Entwicklung zu stoppen und von Anfang an ganze mögliche Testfälle zu schreiben [...]?

Vermächtnis gegeben1 Code, schreiben Sie Unit-Tests in folgenden Situationen:

  • beim Beheben von Fehlern
  • beim Refactoring
  • beim Hinzufügen neuer Funktionen zum vorhandenen Code

So nützlich Unit-Tests auch sind, erstellen Sie eine vollständige Unit-Test-Suite für eine vorhandene1 Codebasis ist wahrscheinlich keine realistische Idee. Die Kräfte, die Sie dazu gedrängt haben, innerhalb einer engen Frist zu liefern. Sie haben Ihnen keine Zeit gelassen, während der Entwicklung angemessene Komponententests zu erstellen. Glauben Sie, dass Sie ausreichend Zeit haben, um Tests für das "funktionierende Programm" zu erstellen?

1Legacy-Code ist der Code ohne Komponententests. Dies ist die TDD-Definition von Legacy-Code. Dies gilt auch dann, wenn der Legacy-Code frisch geliefert wurde [auch wenn die Tinte noch nicht getrocknet ist].

22
Nick Alexeev

Nach meiner Erfahrung benötigen Tests keine vollständige Abdeckung, um hilfreich zu sein. Stattdessen profitieren Sie mit zunehmender Deckung von verschiedenen Vorteilen:

  • mehr als 30% Abdeckung (auch bekannt als ein paar Integrationstests): Wenn Ihre Tests fehlschlagen, ist etwas extrem kaputt (oder Ihre Tests sind schuppig). Zum Glück haben Sie die Tests schnell alarmiert! Releases erfordern jedoch noch umfangreiche manuelle Tests.
  • mehr als 90% Abdeckung (auch bekannt als die meisten Komponenten haben oberflächliche Komponententests): Wenn Ihre Tests erfolgreich sind, ist die Software wahrscheinlich größtenteils in Ordnung. Die nicht getesteten Teile sind Edge-Fälle, was für unkritische Software in Ordnung ist. Für Releases sind jedoch noch einige manuelle Tests erforderlich.
  • sehr hohe Abdeckung von Funktionen/Anweisungen/Zweigen/Anforderungen: Sie leben den Traum von TDD/ BDD , und Ihre Tests spiegeln genau die Funktionalität von wider Ihre Software. Sie können mit hoher Sicherheit umgestalten, einschließlich umfangreicher Architekturänderungen. Wenn die Tests bestanden sind, ist Ihre Software fast freigegeben. nur einige manuelle Rauchprüfungen erforderlich.

Die Wahrheit ist, wenn Sie nicht mit BDD beginnen, werden Sie nie dorthin gelangen, da der Arbeitsaufwand für das Testen nach dem Codieren einfach zu hoch ist. Das Problem ist nicht das Schreiben der Tests, sondern vielmehr das Bewusstsein tatsächliche Anforderungen (statt zufälliger Implementierungsdetails) und die Möglichkeit , die Software auf eine Weise zu entwerfen , die sowohl funktional als auch einfach zu testen ist. Wenn Sie die Tests zuerst oder zusammen mit dem Code schreiben, ist dies praktisch kostenlos.

Da für neue Funktionen Tests erforderlich sind, für Tests jedoch Designänderungen erforderlich sind, für das Refactoring jedoch auch Tests erforderlich sind, besteht ein Problem mit Hühnern und Eiern. Wenn sich Ihre Software einer angemessenen Abdeckung nähert, müssen Sie in den Teilen des Codes, in denen neue Funktionen auftreten, einige sorgfältige Umgestaltungen vornehmen, um die neuen Funktionen testbar zu machen. Dies wird Sie anfangs sehr verlangsamen. Indem nur die Teile überarbeitet und getestet werden, für die Neuentwicklungen erforderlich sind, konzentrieren sich die Tests auch auf den Bereich, in dem sie am dringendsten benötigt werden. Stabiler Code kann ohne Tests fortgesetzt werden: Wenn er fehlerhaft wäre, müssten Sie ihn trotzdem ändern.

Während Sie versuchen, sich an TDD anzupassen, ist die Testabdeckung in Teilen, die geändert werden, eine bessere Metrik als die gesamte Projektabdeckung. Diese Abdeckung sollte von Anfang an sehr hoch sein, obwohl es nicht möglich ist, alle Teile des Codes zu testen, die von einem Refactoring betroffen sind. Außerdem profitieren Sie von den Vorteilen einer hohen Testabdeckung innerhalb der getesteten Komponenten. Das ist nicht perfekt, aber immer noch ziemlich gut.

Beachten Sie, dass Unit-Tests zwar häufig vorkommen, das Beginnen mit den kleinsten Teilen jedoch keine geeignete Strategie ist, um eine ältere Software zu testen. Sie sollten mit Integrationstests beginnen, bei denen ein großer Teil der Software gleichzeitig ausgeführt wird.

Z.B. Ich fand es nützlich, Integrationstestfälle aus realen Protokolldateien zu extrahieren. Das Ausführen solcher Tests kann natürlich viel Zeit in Anspruch nehmen, weshalb Sie möglicherweise einen automatisierten Server einrichten möchten, der die Tests regelmäßig ausführt (z. B. einen durch Commits ausgelösten Jenkins -Server). Die Kosten für die Einrichtung und Wartung eines solchen Servers sind sehr gering im Vergleich zu nicht regelmäßigen Tests, vorausgesetzt, Testfehler werden tatsächlich schnell behoben.

12
amon

Schreiben Sie keine Tests für vorhandenen Code. Es lohnt sich nicht.

Was Sie gemacht haben, wurde bereits auf völlig informelle Weise etwas getestet - Sie haben es ständig von Hand ausprobiert, die Leute haben einige nicht automatisierte Tests durchgeführt, es wird jetzt verwendet. Das bedeutet, dass Sie werden nicht viele Fehler finden.

Was bleibt, sind die Fehler, an die Sie nicht gedacht haben. Aber genau diese werden Sie auch nicht für Unit-Tests halten, sodass Sie sie wahrscheinlich immer noch nicht finden werden.

Ein Grund für TDD ist auch, dass Sie sich vor dem Schreiben Gedanken über die genauen Anforderungen eines Code-Bits machen. Auf welche andere Weise haben Sie das bereits getan.

In der Zwischenzeit ist es immer noch genauso viel Arbeit, diese Tests zu schreiben, wie es gewesen wäre, sie vorher zu schreiben. Es wird viel Zeit kosten, für wenig Nutzen.

Und es ist extrem langweilig, viele, viele Tests ohne Codierung dazwischen zu schreiben und kaum Fehler zu finden. Wenn Sie damit anfangen, werden Leute, die neu bei TDD sind, hassen es.

Kurz gesagt, Entwickler werden es hassen und Manager werden es als kostspielig ansehen, während nicht viele Fehler gefunden werden. Sie werden nie zum eigentlichen TDD-Teil gelangen.

Verwenden Sie es als normalen Teil des Prozesses für Dinge, die Sie ändern möchten.

5
RemcoGerlich

Ein Test ist ein Mittel, um Verständnis zu vermitteln.

Schreiben Sie daher nur Tests für das, was Sie verstehen.

Sie können nur verstehen, was wahr sein sollte, wenn Sie damit arbeiten.

Schreiben Sie daher nur Tests für Code, mit dem Sie arbeiten.

Wenn Sie mit dem Code arbeiten, werden Sie lernen.

Schreiben Sie daher Tests und schreiben Sie sie neu, um zu erfassen, was Sie gelernt haben.

Spülen und wiederholen.

Lassen Sie ein Tool zur Codeabdeckung mit Ihren Tests ausführen und akzeptieren Sie nur Commits für die Hauptleitung, die die Abdeckung nicht verringern. Schließlich erreichen Sie ein hohes Maß an Abdeckung.

Wenn Sie eine Weile nicht mehr mit dem Code gearbeitet haben, muss eine Geschäftsentscheidung getroffen werden. Es ist jetzt wahrscheinlich so ein Vermächtnis, dass niemand in Ihrem Team weiß, wie man damit arbeitet. Es hat wahrscheinlich veraltete Bibliotheken/Compiler/Dokumentationen, was in fast jeder Hinsicht eine massive Belastung darstellt.

Zwei Optionen:

  1. Investieren Sie die Zeit, um es zu lesen, daraus zu lernen, Tests dafür zu schreiben und es umzugestalten. Kleine Änderungssätze mit häufigen Veröffentlichungen.
  2. Finden Sie einen Weg, diese Software loszuwerden. Sie konnten unmöglich eine Änderung daran vornehmen, wenn Sie dazu aufgefordert wurden.
2
Kain0_0

(1) Ist es noch in Ordnung oder eine gute Idee, den größten Teil der Entwicklung zu stoppen und von Anfang an ganze mögliche Testfälle zu schreiben, obwohl (noch!) Alles in Ordnung ist?
(2) Es ist besser, auf etwas Schlimmes zu warten und dann während des Fixes neue Komponententests zu schreiben

Einer der Hauptzwecke von Tests besteht darin, sicherzustellen, dass durch eine Änderung nichts beschädigt wurde. Dies ist ein dreistufiger Prozess:

  1. Bestätigen Sie, dass die Tests erfolgreich waren
  2. Nehmen Sie Änderungen vor
  3. Bestätigen Sie, dass die Tests weiterhin erfolgreich sind

Dies bedeutet, dass Sie Arbeitstests haben müssen vorher Sie ändern tatsächlich etwas. Wenn Sie den zweiten Pfad wählen, bedeutet dies, dass Sie Ihre Entwickler zwingen müssen, Tests zu schreiben, bevor sie den Code überhaupt berühren. Und ich bin der festen Überzeugung, dass die Entwickler den Unit-Tests nicht die Aufmerksamkeit schenken werden, die sie verdienen, wenn sie bereits mit einer realen Veränderung konfrontiert sind.

Daher empfehle ich, die Aufgaben zum Schreiben von Tests und zum Ändern von Änderungen aufzuteilen, um zu vermeiden, dass Entwickler die Qualität der einen für die anderen opfern.

obwohl alles (OK!) komplett funktioniert OKAY?

Um dies ausdrücklich hervorzuheben, ist es ein weit verbreitetes Missverständnis, dass Sie nur Tests benötigen, wenn der Code nicht funktioniert. Sie benötigen Tests, wenn der Code auch funktioniert, um beispielsweise jemandem zu beweisen, dass [neu auftretender Fehler] nicht auf Ihren Teil zurückzuführen ist, da die Tests noch bestehen.
Bestätigen, dass alles noch so funktioniert wie zuvor ist ein wichtiger Vorteil des Testens, den Sie weglassen, wenn Sie implizieren, dass Sie keine Tests benötigen, wenn der Code funktioniert.

(3) Vergessen Sie sogar frühere Codes und schreiben Sie nur Unit-Tests nur für die neuen Codes und verschieben Sie alles auf den nächsten großen Refactor

Im Idealfall sollte der gesamte vorhandene Quellcode jetzt Unit-Tests erhalten. Es gibt jedoch ein vernünftiges Argument dafür, dass der dafür erforderliche Zeit- und Arbeitsaufwand (und die dafür erforderlichen Kosten) für bestimmte Projekte einfach nicht relevant sind.
Beispielsweise können Anwendungen, die nicht mehr entwickelt werden und von denen nicht erwartet wird, dass sie geändert werden (z. B. der Client verwendet sie nicht mehr oder der Client ist kein Client mehr), argumentieren, dass sie nicht relevant sind um diesen Code nicht mehr zu testen.

Es ist jedoch nicht so eindeutig, wo Sie die Linie zeichnen. Dies muss ein Unternehmen in einer Kosten-Nutzen-Analyse berücksichtigen. Das Schreiben von Tests kostet Zeit und Mühe, aber erwarten sie eine zukünftige Entwicklung dieser Anwendung? Wiegen die Gewinne aus Unit-Tests die Kosten für das Schreiben auf?

Dies ist keine Entscheidung, die Sie (als Entwickler) treffen können. Bestenfalls können Sie eine Schätzung für die erforderliche Zeit für die Implementierung von Tests für ein bestimmtes Projekt abgeben, und es ist Sache des Managements, zu entscheiden, ob eine ausreichende Erwartung besteht, das Projekt tatsächlich warten/entwickeln zu müssen.

und alles auf den nächsten großen Refactor verschieben

Wenn der nächste große Refaktor gegeben ist, müssen Sie die Tests tatsächlich schreiben.

Aber verschieben Sie es nicht, bis Sie vor großen Veränderungen stehen. Mein Anfangspunkt (nicht das Schreiben von Tests und das Aktualisieren des Codes zu kombinieren) bleibt bestehen, aber ich möchte hier einen zweiten Punkt hinzufügen: Ihre Entwickler derzeit kennen sich im Projekt besser aus als in sechs Monate, wenn sie diese Zeit damit verbringen, an anderen Projekten zu arbeiten. Profitieren Sie von Zeiträumen, in denen die Entwickler bereits aufgewärmt sind und nicht herausfinden müssen, wie die Dinge in Zukunft wieder funktionieren.

0
Flater

Meine zwei Cent:

Warten Sie auf ein größeres technisches Upgrade des Systems und schreiben Sie die Tests dann ... offiziell mit Unterstützung des Unternehmens.

Angenommen, Sie sind ein SCRUM-Shop, Ihre Arbeitslast wird durch die Kapazität dargestellt und Sie können einen Prozentsatz davon für Unit-Tests verwenden, aber ...

Zu sagen, dass Sie zurückgehen und die Tests schreiben werden, ist naiv. Was Sie wirklich tun werden, ist, Tests zu schreiben, zu refaktorieren und weitere Tests zu schreiben, nachdem der Refaktor den Code testbarer gemacht hat. Deshalb ist es am besten, zu beginnen mit Tests, wie Sie bereits wissen, und ...

Es ist am besten, wenn der ursprüngliche Autor Tests für den zuvor geschriebenen Code schreibt und diesen umgestaltet. Es ist nicht ideal, aber aus Erfahrung möchten Sie, dass der Refactor den Code besser und nicht schlechter macht.

0
RandomUs1r