Ich arbeite an der Entwicklung eines alten Projekts, das in Java geschrieben wurde. Wir haben mehr als 10 Millionen LOC und noch schlimmer mehr als 4000 Funktionstests.
Die von Hudson geplanten Tests scheitern wie verrückt bei jeder größeren Codeänderung. Die Überprüfung des Testfehlers - wenn es sich um ein Produkt- oder Testproblem handelt, dauert es Monate. Wir können die alten Tests nicht entfernen, weil wir nicht wissen, was sie testen!
Was wir tun können? Wie kann man mit einer solchen Anzahl von Legacy-Tests fortfahren?
integration-tests
legacy-code
jenkins
Hector Brosuli
quelle
quelle
Antworten:
Gib sie auf.
Ich weiß, dass es schwierig ist, etwas loszulassen, das eindeutig viel Aufwand bedeutet, aber die Tests funktionieren nicht für Sie, sie arbeiten gegen Sie. Eine Testsuite soll Ihnen die Gewissheit geben, dass das System das tut, was es tun soll. Wenn dies nicht der Fall ist, handelt es sich um eine Verbindlichkeit anstelle eines Vermögenswerts. Es spielt keine Rolle, ob das System oder die Tests fehlerhaft sind - solange die Testsuite große Fehlermengen anzeigt, kann sie ihren Zweck nicht erfüllen.
Was Sie jetzt brauchen , ist eine neue Reihe von Tests , dass Läufe mit keinem Fehler. Das bedeutet, dass es anfangs nur eine geringe, in der Tat fast keine Abdeckung hat. Jedes Mal, wenn Sie sich die Zeit nehmen, etwas über Ihr System zu verstehen, ordnen Sie dieses Wissen in einem Test neu. Mit der Zeit entsteht so ein neues Sicherheitsnetz, auf das Sie in Zukunft aufbauen können. Der Versuch, ein altes, schlecht verstandenes Sicherheitsnetz auszubessern, ist eine Zeitsenke, die sich fast nie lohnt.
Ich würde mich sogar gegen die Übertragung von Tests von der alten Suite auf die neue Suite aussprechen. Sicher, einige von ihnen können jetzt erfolgreich sein, aber liegt das daran, dass sie genau das testen, was sie testen sollen, oder nur daran, dass einige zufällige Schüsse immer das Ziel treffen? Natürlich müssen Sie pragmatisch sein, was mit dem Aufwand, den Sie zur Verfügung haben, getan werden kann und was nicht, aber Sie können keine Kompromisse eingehen, wenn eine Testsuite sauber ausgeführt werden muss, um ihre Aufgabe zu erfüllen .
quelle
Gehen Sie und reparieren Sie die Tests.
Ihr größter Fehler ist, dass Sie zuließen, dass Tests fehlschlagen, und Sie haben es offensichtlich eine Weile ignoriert. Was Sie haben, sind keine "Legacy-Tests" - Sie arbeiten an einem Legacy-Code. Und ich betrachte jeden Code, der ohne Tests geschrieben wurde, als Vermächtnis.
Es sieht so aus, als gäbe es ein noch größeres Problem in Ihrer Organisation, da Sie nicht mit klaren Anforderungen arbeiten. Ich kann nicht verstehen, dass Sie (oder jemand anderes) das richtige Verhalten nicht bestätigen können.
quelle
Tests sind wertvoll. Zumindest berichten sie, dass jemand überlegte, Zeit damit zu verbringen, sie zu schreiben. Vermutlich hatten sie einmal einen gewissen Wert für jemanden. Mit etwas Glück werden sie eine vollständige Auflistung aller Funktionen und Fehler enthalten, an denen das Team jemals gearbeitet hat - obwohl sie möglicherweise auch nur eine Möglichkeit waren, eine willkürliche Testabdeckungszahl zu ermitteln, ohne sorgfältig durchdacht zu werden. Bis Sie sie anschauen, werden Sie nicht wissen, was hier der Fall ist.
Wenn die meisten Ihrer Tests die meiste Zeit bestehen, beißen Sie einfach in die Kugel und investieren Sie Zeit, um herauszufinden, was die wenigen fehlgeschlagenen Tests versuchten, und um sie zu beheben oder zu verbessern, damit die Arbeit beim nächsten Mal einfacher wird. In diesem Fall fahren Sie mit Bestimmen der Absicht für jeden Testabschnitt fort , um Ratschläge zu erhalten, wie mit einer kleinen Anzahl von fehlgeschlagenen Tests verfahren werden kann.
Auf der anderen Seite könnten Sie jetzt mit einem roten Build konfrontiert sein, und Hunderte oder sogar Tausende von Tests, die eine Weile nicht bestanden haben, und Jenkins war lange nicht mehr grün. Zu diesem Zeitpunkt ist der Jenkins-Build-Status unbrauchbar geworden und ein Schlüsselindikator für Probleme beim Einchecken funktioniert nicht mehr. Sie müssen dies beheben, können es sich aber nicht leisten, alle Vorwärtsbewegungen zu stoppen, während Sie das Chaos in Ihrem Wohnzimmer aufräumen.
Damit Sie bei der Durchführung der erforderlichen Archäologie auf Nummer sicher gehen und feststellen können, welcher Wert aus den fehlgeschlagenen Tests wiederhergestellt werden kann, empfehle ich die folgenden Schritte:
Deaktivieren Sie die fehlgeschlagenen Tests vorübergehend.
Es gibt verschiedene Möglichkeiten, wie Sie dies tun können, abhängig von Ihrer Umgebung, die Sie nicht eindeutig beschreiben. Daher kann ich keine bestimmte empfehlen.
Einige Frameworks unterstützen die Vorstellung von erwarteten Fehlern. Wenn dies bei Ihnen der Fall ist, ist dies großartig, da Sie einen Countdown sehen, wie viele Tests in dieser Kategorie noch vorhanden sind, und Sie werden sogar informiert, wenn einige davon unerwartet verlaufen.
Einige Frameworks unterstützen Testgruppen und ermöglichen es Ihnen, Hudson anzuweisen, nur einige der Tests auszuführen oder eine Gruppe der Tests zu überspringen. Dies bedeutet, dass Sie die Testgruppe gelegentlich manuell ausführen können, um festzustellen, ob sie jetzt bestanden hat.
In einigen Frameworks können Sie einzelne zu ignorierende Tests mit Anmerkungen versehen oder auf andere Weise als ignoriert markieren. In diesem Fall ist es schwieriger, sie als Gruppe zu führen, aber es hindert sie daran, Sie abzulenken.
Sie können die Tests in einen Quellbaum verschieben, der normalerweise nicht im Build enthalten ist.
Im Extremfall können Sie den Code aus dem HEAD des Versionskontrollsystems löschen. Dadurch wird es jedoch schwieriger, zu erkennen, wann die dritte Phase abgeschlossen ist.
Das Ziel ist es, Jenkins so schnell wie möglich dazu zu bringen, grün zu werden, damit Sie sich so schnell wie möglich in die richtige Richtung bewegen können.
Halten Sie die Tests aktuell.
Lösen Sie den Vorgang aus, um neue Tests hinzuzufügen, während Sie Code hinzufügen oder ändern, und verpflichten Sie sich, alle bestandenen Tests bestehen zu lassen.
Tests können aus einer Vielzahl von Gründen fehlschlagen, einschließlich der Tatsache, dass es sich anfangs nicht um gut geschriebene Tests handelte. Aber sobald Sie Jenkins grün bekommen, ist es wirklich wichtig, dass es so bleibt.
Gewöhnen Sie sich daran, gute Tests zu schreiben, und machen Sie es zu einer großen Sache, wenn Tests fehlschlagen.
Bestimmen Sie die Absicht für jeden Test.
Führen Sie die deaktivierten Tests nacheinander durch. Beginnen Sie mit den Modulen, die sich auf die Module auswirken, die Sie am häufigsten ändern. Bestimmen Sie die Absicht des Tests und den Grund für den Fehler.
Testet es eine Funktion, die absichtlich aus der Codebasis entfernt wurde? Dann kannst du es wohl löschen.
Fängt es einen Bug, den noch niemand bemerkt hat? Setzen Sie den Test wieder ein und beheben Sie den Fehler.
Schlägt dies fehl, weil ungerechtfertigte Annahmen getroffen wurden (z. B. wurde angenommen, dass der Text der Schaltfläche immer in Englisch ist, aber Sie haben Ihre Anwendung jetzt für mehrere Sprachen lokalisiert)? Finden Sie dann heraus, wie Sie den Test auf eine einzelne Sache konzentrieren und ihn nach besten Kräften von nicht damit zusammenhängenden Änderungen isolieren können.
Verbreitet sich der Test über die gesamte Anwendung und stellt er einen Systemtest dar? Entfernen Sie es dann aus Ihrer Haupt-Jenkins-Testsuite und fügen Sie es der Regressionssuite hinzu, die seltener ausgeführt wird.
Hat sich die Architektur der App bis zur Unkenntlichkeit verändert, sodass der Test nichts mehr nützt? Lösche es.
Wurde der Test hinzugefügt, um die Statistik der Codeabdeckung künstlich zu erhöhen, aber er bestätigt lediglich, dass der Code korrekt kompiliert wurde und nicht in eine Endlosschleife übergeht? Oder bestätigt der Test einfach, dass Ihr ausgewähltes Spott-Framework die Ergebnisse zurückgibt, denen Sie es gerade mitgeteilt haben? Lösche es.
Infolgedessen werden einige Tests bestehen bleiben, einige werden modifiziert, einige werden in mehrere unabhängige, mundgerechte Stücke aufgeteilt und einige werden entfernt. Solange Sie mit den neuen Anforderungen noch Fortschritte machen, müssen Sie ein wenig Zeit für den Umgang mit solchen technischen Schulden einplanen.
quelle
4000 Tests sind ein unlösbares Problem. 40 tests ist mehr tractable. Wählen Sie zufällig eine überschaubare Anzahl von Tests aus, die ausgeführt und analysiert werden sollen. Klassifizieren Sie die Ergebnisse als:
Wenn viele der Tests in die erste Kategorie fallen, ist es möglicherweise an der Zeit, Ihre aktuelle Testsuite zu löschen und eine nützliche für den aktuellen Code zusammenzustellen.
Wenn viele der Tests auf eine Weise fehlschlagen, die Sie über ein Problem in Ihrem Code informiert, müssen Sie die fehlgeschlagenen Tests zur Behebung von Problemen durcharbeiten. Möglicherweise führt die Behebung eines oder zweier Fehler dazu, dass eine große Anzahl von Tests ausgeführt wird.
quelle
Wenn diese Aussage wahr ist,
Das bedeutet dann, dass viele der Tests erneut bestanden werden, wenn Sie kurz vor einer "größeren Codeänderung" ein Rollback auf den Code durchführen. Nehmen Sie danach einen kleineren Teil der Änderungen in die Hand und sehen Sie, welche Tests neu fehlschlagen. Auf diese Weise können Sie besser eingrenzen, welche Codeänderungen dazu führen, dass welche Tests fehlschlagen. Sobald Sie das Problem isoliert haben, sollten Sie in der Lage sein, für jeden Test festzustellen, ob der neue Code fehlerhaft war oder ob der Test fehlerhaft war. Wenn es ein Problem mit dem neuen Code gibt, stellen Sie sicher, dass Sie ihn mit der neuesten Version vergleichen, falls dieser bestimmte Fehler bereits behoben wurde.
Wiederholen Sie diesen Vorgang, bis Sie die neueste Codebasis haben.
Dies mag wie eine überwältigende Aufgabe erscheinen, aber es ist sehr wahrscheinlich, dass, sobald Sie diesen Weg beschritten und einige der Probleme herausgearbeitet haben, ein Muster entsteht, das den Prozess erheblich beschleunigen kann. Beispielsweise:
quelle
Wenn Sie nicht wissen, was sie testen, entfernen Sie sie, bis Sie es wissen. Tests sind fließend. Wenn Sie ein Feature entfernen, das nicht mehr benötigt wird, müssen Sie den Test ändern, der dieses Feature testet. Wenn Sie also nicht wissen, welche Tests durchgeführt werden, haben Sie keine Hoffnung, die Codebasis zu ändern.
Sie können das Testsystem auf den Computern der Entwickler einrichten und dort ausführen, damit die Entwickler sehen können, mit welchen Teilen die Tests interagieren, diese fehlende Dokumentation bereitstellen und sich mit der Codebasis vertraut machen, die Sie entweder nicht richtig ändern oder nicht länger richtig testen.
Kurz gesagt: Wenn Ihre alten Tests beim Vornehmen von Änderungen fehlschlagen, sind Ihre Codeänderungen nicht gut. Verwenden Sie diese Tests als Lernmittel für die Funktionsweise des Systems.
quelle
@Ignore
Annotation - Sie können Ihre Tests behalten, aber nicht ausführen. Dann geht es einfach darum, sie wieder zu aktivieren und nacheinander zu reparieren. Sie können sich auf nur eine Handvoll Tests gleichzeitig konzentrieren, anstatt mit Tausenden von Fehlern überfordert zu sein.Das Wichtigste, was ich tun würde, ist, auf die Grundlagen dessen zurückzukommen, was das Testen tun soll und was das Unternehmen braucht, um in Bewegung zu bleiben. Die Aufgabe von Testing ist es, Probleme zu identifizieren, bevor deren spätere Behebung teuer wird. Ich denke, das Schlüsselwort in diesem Satz ist "teuer". Diese Probleme erfordern eine Geschäftslösung. Zeigen sich teure Probleme vor Ort? In diesem Fall schlägt der Test fehl.
Ihr Management und Sie müssen zu einer Realitätsprüfung kommen. Sie stellen fest, dass die Entwicklungskosten aufgrund einer Reihe älterer Tests in die Höhe schnellen. Wie stehen diese Kosten im Vergleich zu den Kosten für die Lieferung eines fehlerhaften Produkts, weil Sie Tests deaktiviert haben? Wie verhält es sich mit der lästigen Aufgabe, herauszufinden, welche Verhaltensweisen Benutzer benötigen (welche Dinge sollten getestet werden)?
Hierbei handelt es sich um Probleme, für die Geschäftslösungen erforderlich sind, da sie die geschäftliche Seite des Auftrags berühren. Sie liefern ein Produkt an einen Kunden, und das ist eine Grenze, an der das Unternehmen sehr interessiert ist. Sie können möglicherweise Lösungen identifizieren, die Sie als Entwickler nicht erkennen können. Zum Beispiel kann es sinnvoll sein, zwei Produkte anzubieten: ein "Legacy" -Produkt für diejenigen, die Zuverlässigkeit benötigen und bereit sind, auf neue Funktionen zu verzichten, und ein "visionäres" Produkt, das möglicherweise mehr Fehler aufweist, aber zukunftsweisend ist. Dies würde Ihnen die Möglichkeit geben, zwei unabhängige Testreihen zu entwickeln ... eine Legacy-Testreihe mit 4000 Tests und eine mit weiteren Tests, die Sie für erforderlich halten (und dokumentieren, damit sich dieser Prozess nicht wiederholt).
Dann beginnt die Kunst: Wie kann man dieses zweiköpfige Biest so managen, dass Fortschritte in einem Zweig auch dem anderen Zweig helfen? Wie können Ihre Aktualisierungen für den Zweig "visonary" trotz strenger Testanforderungen zurück in den Zweig "legacy" fließen? Wie können fortgesetzte Kundenanfragen in der "Legacy" -Branche Ihr Verständnis für die Anforderungen verbessern, die Ihre Legacy-Kunden benötigen, wenn Sie die Produkte schließlich neu zusammenführen?
quelle
Genau deshalb sollten Sie die alten Tests entfernen! Wenn Sie nicht wissen, was sie tun, ist ein Fehlschlag bedeutungslos und es ist Zeitverschwendung, sie auszuführen. Wirf sie raus und fang von vorne an.
quelle