Angenommen, wir haben eine große Unternehmensanwendung ohne Unit- / Funktionstests. Aufgrund sehr enger Fristen gab es während der Entwicklung keinen testgetriebenen Entwicklungsprozess (Ich weiß, wir sollten niemals enge Fristen versprechen, wenn wir uns nicht sicher sind, aber was getan wird, wird getan!)
Jetzt, da alle Fristen abgelaufen sind und die Dinge ruhig sind, haben sich alle darauf geeinigt, uns in ein produktives TDD / BDD-Team zu verwandeln ... Yay!
Jetzt geht es um den Code, den wir bereits haben: (1) Ist es immer noch in Ordnung oder eine gute Idee, den größten Teil der Entwicklung zu stoppen und von Anfang an mit dem Schreiben aller möglichen Testfälle zu beginnen, obwohl (noch) alles in Ordnung ist? ? Oder (2) es ist besser zu warten, bis etwas Schlimmes passiert, und dann während des Fixes neue Unit-Tests zu schreiben, oder (3) sogar frühere Codes zu vergessen und nur Unit-Tests für die neuen Codes zu schreiben und alles auf den nächsten großen Refactor zu verschieben.
Es gibt ein paar gute und verwandte Artikel wie diesen . 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 eine völlig unangenehme Situation in einem Entwicklungsteam. 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 Entwicklungsleiter ist für solch ein Durcheinander verantwortlich! Aber was getan ist, ist auch getan. Wenn möglich, stimmen Sie nicht ab, nur weil Sie der Meinung sind, dass dies niemals passieren sollte.
quelle
int
Wert akzeptiert und etwas Bestimmtes zurückgibt, ist es nicht möglich, einen Unit-Test für jeden möglichenint
Wert zu schreiben , aber es ist wahrscheinlich sinnvoll, eine Handvoll nützlicher Werte zu testen, die das auslösen könnten Code, z. B. negative Zahlen (einschließlichminint
), Nullmaxint
usw., um sicherzustellen, dass einige Randfälle abgedeckt sind.Antworten:
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 TDD Sie verlangsamt und Sie eine Frist verpassen wird.
Solange Sie das so sehen, sind Sie noch nicht bereit für TDD. TDD ist nicht etwas, in das Sie allmählich nachlassen können. Entweder weißt du, wie es geht, oder du weißt es nicht. Wenn Sie es auf halbem Weg versuchen, werden Sie es schaffen und sich selbst sehen schlecht aus.
TDD sollten Sie zuerst zu Hause üben. Lerne es zu tun, denn es hilft dir jetzt beim Programmieren . Nicht, weil dir jemand gesagt hätte, dass du es tun sollst. Nicht, weil es hilft, wenn Sie später Änderungen vornehmen. Wenn es zu etwas wird, das Sie tun, weil Sie es eilig haben, dann sind Sie bereit, es professionell zu tun.
TDD ist etwas, was Sie in jedem Geschäft tun können . Sie müssen nicht einmal Ihren Testcode einreichen. 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.
Auf der anderen Seite sollten Sie bedenken, dass es nicht Ihre Aufgabe ist, Tests einzuchecken, wenn andere Ihre Tests lieben und ausführen. Es geht darum, bewährten Produktionscode zu erstellen. Wenn es testbar ist, ordentlich.
Wenn Sie der Meinung sind, dass das Management an TDD glauben muss oder dass Ihre Kollegen Ihre Tests unterstützen müssen, ignorieren Sie das Beste, was TDD für Sie tut. Es zeigt Ihnen schnell den Unterschied zwischen der Funktionsweise Ihres Codes und der tatsächlichen Funktionsweise.
Wenn Sie nicht sehen können, wie Sie auf diese Weise einen Termin schneller einhalten können, sind Sie für TDD bei der Arbeit noch nicht bereit. Sie müssen zu Hause üben.
Das heißt, es ist schön, wenn das Team Ihre Tests nutzen kann, um Ihren Produktionscode zu lesen, und wenn das Management schicke neue TDD-Tools kauft.
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. 100% Codeabdeckung ist kostenpflichtig. Ignorieren Sie nicht das Gesetz der Ertragsminderung, nur weil es schwierig ist, ein Urteil zu fällen.
Sparen Sie Ihre Test-Energie für die interessante Geschäftslogik. Das Zeug, das Entscheidungen trifft und Richtlinien durchsetzt. Testen Sie das Heck raus. Langweiliger, leicht zu lesender struktureller Klebercode, der nur das Zeug zusammendrahtet, muss nicht annähernd so schlecht getestet werden.
Nein. Das ist "Lass uns ein vollständiges Umschreiben machen". Dies zerstört hart erarbeitetes Wissen. Bitten Sie das Management nicht um etwas Zeit, um Tests zu schreiben. Schreiben Sie einfach Tests. Sobald Sie wissen, was Sie tun, werden Sie durch Tests nicht mehr gebremst.
Ich beantworte 2 und 3 auf die gleiche Weise. Wenn Sie den Code aus irgendeinem Grund ändern, ist es sehr schön, wenn Sie einen Test machen können. Wenn es sich bei dem Code um ein Legacy handelt, wird derzeit kein Test begrüßt. Was bedeutet, dass es schwierig ist, es zu testen, bevor es geändert wird. Nun, da du es sowieso änderst, kannst du es in etwas Testbares verwandeln und es testen.
Das ist die nukleare Option. Es ist riskant. Sie nehmen Änderungen ohne Tests vor. Es gibt einige kreative Tricks, um älteren 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 . Probieren Sie es aus und Sie werden sehen, dass Sie nicht alles Alte abbrennen müssen, um etwas Neues zu machen.
quelle
Schreiben Sie in den folgenden Situationen Komponententests, wenn Sie den Code für Legacy 1 erhalten haben :
So nützlich Unit-Tests auch sind, wahrscheinlich ist es keine realistische Idee , eine vollständige Unit-Test-Suite für eine vorhandene 1- Codebasis zu erstellen . 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 "Programm, das funktioniert" zu erstellen?
1 Legacy-Code ist der Code ohne Komponententests. Dies ist die TDD-Definition des Legacy-Codes. Dies gilt auch dann, wenn der Legacy-Code frisch geliefert wurde (auch wenn die Tinte noch nicht getrocknet ist).
quelle
Meiner Erfahrung nach müssen Tests nicht vollständig abgedeckt sein, um hilfreich zu sein. Stattdessen profitieren Sie mit zunehmender Abdeckung von verschiedenen Vorteilen:
Die Wahrheit ist, wenn Sie nicht mit BDD anfangen, werden Sie nie dorthin gelangen, da der Aufwand zum Testen nach dem Codieren einfach zu hoch ist. Das Problem ist nicht das Schreiben der Tests, aber um so mehr ist sich bewusst von den tatsächlichen Bedarf ( und nicht als zufällige Implementierungsdetails) und in der Lage zu entwerfen , um die Software in einer Weise , die sowohl funktional und 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 Änderungen am Design erforderlich sind, für das Refactoring jedoch auch Tests erforderlich sind, besteht ein gewisses Henne-Ei-Problem. Wenn sich Ihre Software einer angemessenen Abdeckung nähert, müssen Sie die Teile des Codes, in denen neue Funktionen auftreten, sorgfältig überarbeiten, um die neuen Funktionen testbar zu machen. Dies verlangsamt Sie sehr - zunächst. Indem nur die Teile überarbeitet und getestet werden, für die eine Neuentwicklung erforderlich ist, 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, eine Anpassung an TDD vorzunehmen, ist die Testabdeckung in Teilen, die geändert werden, eine bessere Metrik als die Gesamtabdeckung des Projekts. 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 meisten Vorteilen einer hohen Testabdeckung in den getesteten Komponenten. Das ist nicht perfekt, aber trotzdem ziemlich gut.
Beachten Sie, dass Unit-Tests anscheinend weit verbreitet sind. Das Beginnen mit den kleinsten Teilen ist jedoch keine geeignete Strategie, um eine ältere Software zu testen. Beginnen Sie mit Integrationstests, bei denen ein großer Teil der Software gleichzeitig ausgeführt wird.
ZB fand ich 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, auf dem die Tests regelmäßig ausgeführt werden (z. B. ein Jenkins- Server, der durch Commits ausgelöst wird). Die Kosten für die Einrichtung und Wartung eines solchen Servers sind sehr gering, verglichen mit der Nichtdurchführung von Tests, vorausgesetzt, Testfehler werden tatsächlich schnell behoben.
quelle
Schreiben Sie keine Tests für vorhandenen Code. Es lohnt sich nicht.
Was Sie gemacht haben, wurde bereits auf eine völlig informelle Weise 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 nicht viele Fehler finden .
Was übrig bleibt, sind die Fehler, über die Sie nicht nachgedacht haben. Aber genau für diese werden Sie wahrscheinlich auch keine Komponententests schreiben, sodass Sie sie wahrscheinlich immer noch nicht finden werden.
Ein Grund für TDD besteht auch darin, sich vor dem Schreiben Gedanken darüber zu machen, welche genauen Anforderungen an ein Stück Code gestellt werden. Wie auch immer, du hast das schon getan.
In der Zwischenzeit ist es noch genauso viel Arbeit, diese Tests zu schreiben, wie es gewesen wäre, sie vorher zu schreiben. Es wird viel Zeit kosten, bei geringem Nutzen.
Und es ist extrem langweilig , viele, viele Tests ohne dazwischen liegende Codierung zu schreiben und kaum Fehler zu finden. Wenn Sie damit anfangen, hassen es die TDD- Neulinge .
Kurz gesagt, Entwickler werden es hassen und Manager werden es als kostspielig ansehen, während nicht viele Fehler gefunden werden. Sie gelangen nie zum eigentlichen TDD-Teil.
Verwenden Sie es für Dinge, die Sie ändern möchten, als normalen Teil des Prozesses.
quelle
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 das zu erfassen, was Sie gelernt haben.
Spülen und wiederholen.
Lassen Sie ein Code-Coverage-Tool mit Ihren Tests ausführen und akzeptieren Sie nur Festschreibungen für die Hauptlinie, die die Coverage nicht reduzieren. Schließlich erreichen Sie einen hohen Abdeckungsgrad.
Wenn Sie eine Weile nicht mehr mit dem Code gearbeitet haben, muss eine Geschäftsentscheidung getroffen werden. Es ist jetzt so wahrscheinlich, dass niemand in Ihrem Team weiß, wie man damit arbeitet. Es hat wahrscheinlich veraltete Bibliotheken / Compiler / Dokumentationen, was in jeder Hinsicht eine massive Haftung darstellt.
Zwei Optionen:
quelle
Einer der Hauptzwecke von Tests ist es, sicherzustellen, dass eine Änderung nichts kaputt macht. Dies ist ein dreistufiger Prozess:
Dies bedeutet, dass Sie Arbeitstests durchführen müssen, bevor Sie tatsächlich etwas ändern. Wenn Sie sich für den zweiten Pfad entscheiden, müssen Sie Ihre Entwickler zwingen, Tests zu schreiben, bevor sie überhaupt den Code berühren. Und ich bin der festen Überzeugung, dass die Entwickler den Unit-Tests nicht die Aufmerksamkeit schenken werden, die sie verdienen, wenn sie sich bereits einer realen Veränderung gegenübersehen.
Ich schlage daher vor, die Aufgaben für das Schreiben von Tests und das Ändern von Änderungen aufzuteilen, um zu vermeiden, dass Entwickler die Qualität des einen für das andere opfern.
Nur um dies zu verdeutlichen, ist es ein weit verbreitetes Missverständnis, dass Sie nur dann 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 an Ihrem Teil liegt, da die Tests noch bestehen.
Das Bestätigen, dass alles noch so funktioniert wie zuvor, ist ein wichtiger Vorteil von Tests, die Sie auslassen, wenn Sie implizieren, dass Sie keine Tests benötigen, wenn der Code funktioniert.
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 Aufwand (und die Kosten) für bestimmte Projekte einfach nicht relevant sind.
Wenn beispielsweise eine Anwendung nicht mehr entwickelt wird und voraussichtlich nicht mehr geändert wird (z. B. der Client sie nicht mehr verwendet oder der Client kein Client mehr ist), können Sie argumentieren, dass es nicht mehr relevant ist, diesen Code 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 für diese Anwendung? Wiegen die Gewinne aus Unit-Tests die Kosten für das Schreiben dieser Tests auf?
Dies ist keine Entscheidung, die Sie (als Entwickler) treffen können. Bestenfalls können Sie einen Kostenvoranschlag für die erforderliche Zeit für die Implementierung von Tests für ein bestimmtes Projekt erstellen. Das Management kann dann entscheiden, ob die Erwartung ausreichend ist, dass das Projekt tatsächlich gewartet / weiterentwickelt werden muss.
Wenn der nächste große Refaktor vorgegeben ist, müssen Sie die Tests in der Tat schreiben.
Aber verschiebe es nicht, bis du vor großen Veränderungen stehst. Mein erster Punkt (das Schreiben von Tests und das Aktualisieren des Codes nicht zu kombinieren) bleibt bestehen, aber ich möchte hier einen zweiten Punkt hinzufügen: Ihre Entwickler kennen sich derzeit im Projekt besser aus als in sechs Monaten, wenn sie diese Zeit damit verbringen, zu arbeiten bei anderen Projekten. Profitieren Sie von Zeiträumen, in denen die Entwickler bereits aufgewärmt sind und nicht mehr herausfinden müssen, wie die Dinge in Zukunft wieder funktionieren.
quelle
Meine zwei Cent:
Warten Sie auf ein größeres technisches Upgrade des Systems und schreiben Sie die Tests dann ... offiziell mit der Unterstützung des Unternehmens.
Nehmen wir alternativ an, Sie sind ein SCRUM-Shop, Ihre Arbeitsbelastung wird durch die Kapazität dargestellt und Sie können einen Prozentsatz davon für Unit-Tests zuweisen, aber ...
Zu sagen, dass Sie zurückgehen und die Tests schreiben werden, ist naiv. Sie werden wirklich Tests schreiben, umgestalten und weitere Tests schreiben, nachdem der Code durch den Umgestalter testbarer gemacht wurde. Aus diesem Grund ist es am besten, mit dem Schreiben zu beginnen mit Tests, wie Sie bereits wissen, und ...
Für den ursprünglichen Autor ist es am besten, Tests für den zuvor geschriebenen Code zu schreiben und ihn umzugestalten. Dies ist nicht ideal, aber erfahrungsgemäß soll der Refactor den Code besser und nicht schlechter machen.
quelle