Wir haben eine große plattformübergreifende Anwendung, die in C geschrieben ist (mit einer kleinen, aber wachsenden Menge an C ++). Sie hat sich im Laufe der Jahre mit vielen Funktionen weiterentwickelt, die Sie von einer großen C / C ++ - Anwendung erwarten würden:
#ifdef
Hölle- Große Dateien, die es schwierig machen, testbaren Code zu isolieren
- Funktionen, die zu komplex sind, um leicht getestet werden zu können
Da dieser Code für eingebettete Geräte bestimmt ist, ist es sehr aufwändig, ihn auf dem eigentlichen Ziel auszuführen. Daher möchten wir mehr von unserer Entwicklung und unseren Tests in schnellen Zyklen auf einem lokalen System durchführen. Wir möchten jedoch die klassische Strategie "Kopieren / Einfügen in eine C-Datei auf Ihrem System, Beheben von Fehlern, Kopieren / Einfügen zurück" vermeiden. Wenn Entwickler sich die Mühe machen, dies zu tun, möchten wir in der Lage sein, dieselben Tests später neu zu erstellen und automatisiert auszuführen.
Hier ist unser Problem: Um den Code modularer zu gestalten, muss er testbarer sein. Um jedoch automatisierte Komponententests einzuführen, müssen diese modularer sein.
Ein Problem ist, dass wir, da unsere Dateien so groß sind, möglicherweise eine Funktion in einer Datei haben, die eine Funktion in derselben Datei aufruft , die wir für einen guten Komponententest stubben müssen. Es scheint, dass dies weniger problematisch wäre, da unser Code modularer wird, aber das ist noch weit entfernt.
Eine Sache, über die wir nachgedacht haben, war das Markieren des Quellcodes "bekanntermaßen testbar" mit Kommentaren. Dann könnten wir ein Skript-Scan-Quelldateien für testbaren Code schreiben, es in einer separaten Datei kompilieren und es mit den Unit-Tests verknüpfen. Wir könnten die Komponententests langsam einführen, wenn wir Fehler beheben und mehr Funktionen hinzufügen.
Es besteht jedoch die Sorge, dass die Aufrechterhaltung dieses Schemas (zusammen mit allen erforderlichen Stub-Funktionen) zu mühsam wird und die Entwickler die Wartung der Komponententests einstellen. Ein anderer Ansatz besteht darin, ein Tool zu verwenden, das automatisch Stubs für den gesamten Code generiert und die Datei damit verknüpft. (Das einzige Tool, das wir gefunden haben, um dies zu tun, ist ein teures kommerzielles Produkt.) Dieser Ansatz scheint jedoch zu erfordern, dass unser gesamter Code modularer ist, bevor wir überhaupt beginnen können, da nur die externen Aufrufe gelöscht werden können.
Persönlich möchte ich Entwickler lieber über ihre externen Abhängigkeiten nachdenken lassen und intelligent ihre eigenen Stubs schreiben. Dies könnte jedoch überwältigend sein, um alle Abhängigkeiten für eine schrecklich überwachsene Datei mit 10.000 Zeilen zu beseitigen. Es mag schwierig sein, Entwickler davon zu überzeugen, dass sie Stubs für alle ihre externen Abhängigkeiten verwalten müssen, aber ist das der richtige Weg, dies zu tun? (Ein weiteres Argument, das ich gehört habe, ist, dass der Betreuer eines Subsystems die Stubs für sein Subsystem verwalten sollte. Aber ich frage mich, ob das "Erzwingen" von Entwicklern, ihre eigenen Stubs zu schreiben, zu besseren Unit-Tests führen würde?)
Das #ifdefs
fügt dem Problem natürlich eine weitere ganze Dimension hinzu.
Wir haben uns mehrere C / C ++ - basierte Unit-Test-Frameworks angesehen, und es gibt viele Optionen, die gut aussehen. Wir haben jedoch nichts gefunden, was den Übergang von "Haarball des Codes ohne Unit-Tests" zu "Unit-testbarem Code" erleichtern könnte.
Hier sind meine Fragen an alle anderen, die dies durchgemacht haben:
- Was ist ein guter Ausgangspunkt? Gehen wir in die richtige Richtung oder fehlt uns etwas Offensichtliches?
- Welche Tools könnten hilfreich sein, um den Übergang zu erleichtern? (vorzugsweise Free / Open Source, da unser Budget derzeit ungefähr "Null" ist)
Beachten Sie, dass unsere Build-Umgebung auf Linux / UNIX basiert, sodass wir keine Nur-Windows-Tools verwenden können.
Antworten:
Wie traurig - keine wundersame Lösung - nur viel harte Arbeit, um Jahre akkumulierter technischer Schulden zu korrigieren .
Es gibt keinen einfachen Übergang. Sie haben ein großes, komplexes und ernstes Problem.
Sie können es nur in winzigen Schritten lösen. Jeder winzige Schritt beinhaltet Folgendes.
Wählen Sie einen diskreten Code, der unbedingt erforderlich ist. (Knabbern Sie nicht an den Rändern des Mülls.) Wählen Sie eine Komponente aus, die wichtig ist und - irgendwie - aus dem Rest herausgeschnitten werden kann. Während eine einzelne Funktion ideal ist, kann es sich um einen verworrenen Funktionscluster oder eine ganze Funktionsdatei handeln. Es ist in Ordnung, mit etwas zu beginnen, das für Ihre testbaren Komponenten nicht perfekt ist.
Finde heraus, was es tun soll. Finde heraus, was die Schnittstelle sein soll. Dazu müssen Sie möglicherweise ein erstes Refactoring durchführen, um Ihr Zielstück tatsächlich diskret zu machen.
Schreiben Sie einen "Gesamt" -Integrationstest, der Ihren diskreten Code vorerst mehr oder weniger so testet, wie er gefunden wurde. Lassen Sie dies bestehen, bevor Sie versuchen, etwas Wesentliches zu ändern.
Refaktorieren Sie den Code in ordentliche, testbare Einheiten, die sinnvoller sind als Ihr aktueller Haarball. Sie müssen (vorerst) eine gewisse Abwärtskompatibilität mit Ihrem Gesamtintegrationstest aufrechterhalten.
Schreiben Sie Komponententests für die neuen Einheiten.
Wenn alles vorbei ist, deaktivieren Sie die alte API und beheben Sie, was durch die Änderung beschädigt wird. Überarbeiten Sie gegebenenfalls den ursprünglichen Integrationstest. Es testet die alte API. Sie möchten die neue API testen.
Iterieren.
quelle
Michael Feathers schrieb die Bibel dazu und arbeitete effektiv mit Legacy Code
quelle
Meine kleine Erfahrung mit Legacy-Code und der Einführung von Tests wäre es, die " Charakterisierungstests ". Sie erstellen Tests mit bekannter Eingabe und erhalten dann die Ausgabe. Diese Tests sind nützlich für Methoden / Klassen, bei denen Sie nicht wissen, was sie wirklich tun, aber Sie wissen, dass sie funktionieren.
Es gibt jedoch manchmal Fälle, in denen es fast unmöglich ist, Komponententests zu erstellen (sogar Charakterisierungstests). In diesem Fall greife ich das Problem durch Abnahmetests an ( greife in diesem Fall Fitnesse ).
Sie erstellen die gesamte Klasse von Klassen, die zum Testen einer Funktion erforderlich sind, und überprüfen sie auf Fitness. Es ähnelt "Charakterisierungstests", ist aber eine Stufe höher.
quelle
Wie George sagte, ist die effektive Arbeit mit Legacy Code die Bibel für solche Dinge.
Die andere Möglichkeit für andere in Ihrem Team besteht jedoch darin, sich persönlich davon zu überzeugen, dass die Tests weiterhin funktionieren.
Um dies zu erreichen, benötigen Sie ein Testframework, mit dem Sie so einfach wie möglich arbeiten können. Planen Sie für andere Entwickler, dass Sie Ihre Tests als Beispiele verwenden, um ihre eigenen zu schreiben. Wenn sie keine Erfahrung mit Unit-Tests haben und nicht erwarten, dass sie Zeit mit dem Erlernen eines Frameworks verbringen, werden sie das Schreiben von Unit-Tests wahrscheinlich als Verlangsamung ihrer Entwicklung ansehen. Wenn sie das Framework nicht kennen, ist dies eine Ausrede, um die Tests zu überspringen.
Verbringen Sie einige Zeit mit der kontinuierlichen Integration mithilfe von Tempomat, Luntbuild, CDash usw. Wenn Ihr Code jede Nacht automatisch kompiliert wird und Tests ausgeführt werden, werden Entwickler die Vorteile erkennen, wenn Unit-Tests vor der Qa Fehler erkennen.
Eine Sache, die gefördert werden sollte, ist der gemeinsame Besitz von Code. Wenn ein Entwickler seinen Code ändert und den Test einer anderen Person bricht, sollte er nicht erwarten, dass diese Person seinen Test repariert. Er sollte untersuchen, warum der Test nicht funktioniert, und ihn selbst reparieren. Nach meiner Erfahrung ist dies eines der am schwierigsten zu erreichenden Dinge.
Die meisten Entwickler schreiben eine Art Unit-Test, manchmal ein kleines Stück Wegwerfcode, den sie nicht einchecken oder in den Build integrieren. Machen Sie die Integration dieser in den Build einfach und Entwickler werden anfangen, sich einzukaufen.
Mein Ansatz ist es, Tests für neuen hinzuzufügen, und wenn der Code geändert wird, können Sie manchmal nicht so viele oder so detaillierte Tests hinzufügen, wie Sie möchten, ohne zu viel vorhandenen Code zu entkoppeln.
Der einzige Ort, an dem ich auf Unit-Tests bestehe, ist plattformspezifischer Code. Wenn #ifdefs durch plattformspezifische Funktionen / Klassen höherer Ebenen ersetzt werden, müssen diese auf allen Plattformen mit denselben Tests getestet werden. Dies spart viel Zeit beim Hinzufügen neuer Plattformen.
Wir verwenden boost :: test, um unseren Test zu strukturieren. Die einfachen selbstregistrierenden Funktionen erleichtern das Schreiben von Tests.
Diese sind in CTest (Teil von CMake) eingeschlossen. Dadurch wird eine Gruppe von ausführbaren Unit-Test-Dateien gleichzeitig ausgeführt und ein einfacher Bericht erstellt.
Unser nächtlicher Build wird mit Ant und Luntbuild automatisiert (Ant Glues C ++, .net und Java Builds).
Bald hoffe ich, dem Build automatisierte Bereitstellungs- und Funktionstests hinzuzufügen.
quelle
Genau das tun wir gerade. Vor drei Jahren trat ich dem Entwicklungsteam bei einem Projekt bei, das keine Komponententests, fast keine Codeüberprüfungen und einen ziemlich ad-hoc-Erstellungsprozess aufwies.
Die Codebasis besteht aus einer Reihe von COM-Komponenten (ATL / MFC), einer plattformübergreifenden C ++ - Oracle-Datenkassette und einigen Java-Komponenten, die alle eine plattformübergreifende C ++ - Kernbibliothek verwenden. Ein Teil des Codes ist fast ein Jahrzehnt alt.
Der erste Schritt war das Hinzufügen einiger Komponententests. Leider ist das Verhalten sehr datengesteuert, so dass einige anfängliche Anstrengungen unternommen wurden, um ein Unit-Test-Framework (ursprünglich CppUnit, jetzt erweitert auf andere Module mit JUnit und NUnit) zu generieren, das Testdaten aus einer Datenbank verwendet. Die meisten anfänglichen Tests waren Funktionstests, bei denen die äußersten Schichten trainiert wurden, und keine wirklichen Einheitentests. Sie müssen wahrscheinlich einige Anstrengungen unternehmen (die Sie möglicherweise budgetieren müssen), um ein Testkabel zu implementieren.
Ich finde es sehr hilfreich, wenn Sie die Kosten für das Hinzufügen von Unit-Tests so gering wie möglich halten. Das Test-Framework machte es relativ einfach, Tests hinzuzufügen, wenn Fehler in vorhandenen Funktionen behoben wurden. Neuer Code kann ordnungsgemäße Komponententests enthalten. Wenn Sie neue Codebereiche umgestalten und implementieren, können Sie geeignete Komponententests hinzufügen, mit denen viel kleinere Codebereiche getestet werden.
Im letzten Jahr haben wir die kontinuierliche Integration mit CruiseControl hinzugefügt und unseren Erstellungsprozess automatisiert. Dies ist ein viel größerer Anreiz, die Tests auf dem neuesten Stand zu halten und zu bestehen, was in den frühen Tagen ein großes Problem war. Daher würde ich empfehlen, dass Sie regelmäßige (mindestens nächtliche) Unit-Testläufe als Teil Ihres Entwicklungsprozesses einbeziehen.
Wir haben uns kürzlich darauf konzentriert, unseren Codeüberprüfungsprozess zu verbessern, der ziemlich selten und ineffektiv war. Die Absicht ist, es viel billiger zu machen, eine Codeüberprüfung zu initiieren und durchzuführen, damit Entwickler dazu ermutigt werden, sie häufiger durchzuführen. Auch im Rahmen unserer Prozessverbesserung versuche ich, Zeit für Codeüberprüfungen und Komponententests, die in die Projektplanung einbezogen werden, auf einer viel niedrigeren Ebene zu erhalten, um sicherzustellen, dass einzelne Entwickler mehr über sie nachdenken müssen, während es zuvor nur einen festen Anteil gab Zeit, die ihnen gewidmet war, war viel einfacher, sich im Zeitplan zu verlieren.
quelle
Ich habe sowohl an Green Field-Projekten mit vollständig einheitlich getesteten Codebasen als auch an großen C ++ - Anwendungen gearbeitet, die über viele Jahre gewachsen sind, und mit vielen verschiedenen Entwicklern.
Ehrlich gesagt würde ich mich nicht darum kümmern, eine Legacy-Codebasis in den Zustand zu versetzen, in dem Unit-Tests und Test First Development einen großen Mehrwert bieten können.
Sobald eine Legacy-Codebasis eine bestimmte Größe und Komplexität erreicht hat, wird sie zu einer Aufgabe, die einer vollständigen Neufassung entspricht.
Das Hauptproblem besteht darin, dass Sie, sobald Sie mit dem Refactoring für die Testbarkeit beginnen, Fehler einführen. Und erst wenn Sie eine hohe Testabdeckung erhalten, können Sie davon ausgehen, dass all diese neuen Fehler gefunden und behoben werden.
Das bedeutet, dass Sie entweder sehr langsam und vorsichtig vorgehen und erst in Jahren die Vorteile einer gut einheitlich getesteten Codebasis erhalten. (Wahrscheinlich nie seit Fusionen usw.) In der Zwischenzeit führen Sie wahrscheinlich einige neue Fehler ein, die für den Endbenutzer der Software keinen offensichtlichen Wert haben.
Oder Sie gehen schnell, haben aber eine instabile Codebasis, bis Sie eine hohe Testabdeckung Ihres gesamten Codes erreicht haben. (Sie haben also zwei Niederlassungen, eine in Produktion, eine für die Unit-getestete Version.)
Natürlich ist dies alles eine Frage des Maßstabs für einige Projekte. Ein Umschreiben kann nur einige Wochen dauern und kann sich auf jeden Fall lohnen.
quelle
Ein zu berücksichtigender Ansatz besteht darin, zunächst ein systemweites Simulationsframework einzurichten, mit dem Sie Integrationstests entwickeln können. Das Beginnen mit Integrationstests mag kontraintuitiv erscheinen, aber die Probleme bei der Durchführung echter Unit-Tests in der von Ihnen beschriebenen Umgebung sind gewaltig. Wahrscheinlich mehr als nur die Simulation der gesamten Laufzeit in Software ...
Dieser Ansatz würde einfach Ihre aufgelisteten Probleme umgehen - obwohl er Ihnen viele verschiedene Probleme geben würde. In der Praxis habe ich jedoch festgestellt, dass Sie mit einem robusten Integrationstest-Framework Tests entwickeln können, die Funktionen auf Einheitenebene ausüben, allerdings ohne Einheitenisolation.
PS: Erwägen Sie, ein befehlsgesteuertes Simulationsframework zu schreiben, das möglicherweise auf Python oder Tcl basiert. Auf diese Weise können Sie ganz einfach Skripttests durchführen ...
quelle
Tag auch,
Ich würde zunächst einen Blick auf offensichtliche Punkte werfen, z. B. die Verwendung von Dez. in Header-Dateien für einen.
Schauen Sie sich dann an, wie der Code angelegt wurde. Ist es logisch? Fangen Sie vielleicht an, große Dateien in kleinere zu zerlegen.
Vielleicht holen Sie sich ein Exemplar von Jon Lakos 'ausgezeichnetem Buch "Large-Scale C ++ Software Design" ( bereinigter Amazon-Link ), um einige Ideen zu erhalten, wie es aufgebaut sein sollte.
Sobald Sie anfangen, ein bisschen mehr Vertrauen in die Codebasis selbst zu haben, dh das Code-Layout wie im Dateilayout, und einige der schlechten Gerüche beseitigt haben, z. B. die Verwendung von Dez. in Header-Dateien, können Sie einige Funktionen auswählen, die Sie können Verwenden Sie diese Option, um mit dem Schreiben Ihrer Komponententests zu beginnen.
Wählen Sie eine gute Plattform, ich mag CUnit und CPPUnit, und gehen Sie von dort aus.
Es wird jedoch eine lange, langsame Reise.
HTH
Prost,
quelle
Es ist viel einfacher, es zuerst modularer zu gestalten. Mit vielen Abhängigkeiten kann man etwas nicht wirklich vereinheitlichen. Wann umgestaltet werden muss, ist eine schwierige Berechnung. Sie müssen wirklich die Kosten und Risiken gegen die Vorteile abwägen. Wird dieser Code ausgiebig wiederverwendet? Oder wird sich dieser Code wirklich nicht ändern? Wenn Sie vorhaben, es weiterhin zu nutzen, möchten Sie es wahrscheinlich umgestalten.
Klingt so, als ob Sie umgestalten möchten. Sie müssen zunächst die einfachsten Dienstprogramme ausbrechen und darauf aufbauen. Sie haben Ihr C-Modul, das eine Unmenge von Dingen erledigt. Vielleicht gibt es dort einen Code, der Zeichenfolgen immer auf eine bestimmte Weise formatiert. Möglicherweise kann dies als eigenständiges Dienstprogrammmodul herausgestellt werden. Sie haben Ihr neues Zeichenfolgenformatierungsmodul und den Code lesbarer gemacht. Es ist schon eine Verbesserung. Sie behaupten, dass Sie sich in einer Situation befinden. Das bist du wirklich nicht. Durch einfaches Verschieben haben Sie den Code lesbarer und wartbarer gemacht.
Jetzt können Sie eine Unittest für dieses ausgebrochene Modul erstellen. Sie können das auf verschiedene Arten tun. Sie können eine separate App erstellen, die nur Ihren Code enthält und eine Reihe von Fällen in einer Hauptroutine auf Ihrem PC ausführt, oder eine statische Funktion namens "UnitTest" definieren, die alle Testfälle ausführt und "1" zurückgibt, wenn sie erfolgreich sind. Dies könnte auf dem Ziel ausgeführt werden.
Vielleicht können Sie mit diesem Ansatz nicht 100% gehen, aber es ist ein Anfang, und es kann dazu führen, dass Sie andere Dinge sehen, die leicht in testbare Dienstprogramme aufgeteilt werden können.
quelle
Ich denke, im Grunde haben Sie zwei verschiedene Probleme:
Modularisierung, Refactoring, Einfügen von Unit-Tests und dergleichen ist eine schwierige Aufgabe, und ich bezweifle, dass jedes Tool größere Teile dieser Arbeit übernehmen könnte. Es ist eine seltene Fähigkeit. Einige Programmierer können das sehr gut. Die meisten hassen es.
Eine solche Aufgabe mit einem Team zu erledigen, ist mühsam. Ich bezweifle stark, dass das "Erzwingen" von Entwicklern jemals funktionieren wird. Iains Gedanken sind sehr gut, aber ich würde in Betracht ziehen, einen oder zwei Programmierer zu finden, die in der Lage sind und die Quellen "bereinigen" wollen: Refactor, Modualrize, Unit Tests einführen usw. Lassen Sie diese Leute den Job machen und die anderen stellen neue vor Bugs, Aehm-Funktionen. Nur Menschen, die diese Art von Arbeit mögen , werden mit diesem Job Erfolg haben.
quelle
Machen Sie die Verwendung von Tests einfach.
Ich würde damit beginnen, die "Läufe automatisch" einzurichten. Wenn Sie möchten, dass Entwickler (einschließlich Sie selbst) Tests schreiben, machen Sie es einfach, sie auszuführen und die Ergebnisse anzuzeigen.
Das Schreiben eines Tests mit drei Zeilen, das Ausführen mit dem neuesten Build und das Anzeigen der Ergebnisse sollten nur einen Klick entfernt sein und den Entwickler nicht an die Kaffeemaschine senden.
Dies bedeutet, dass Sie einen neuesten Build benötigen. Möglicherweise müssen Sie die Richtlinien für die Arbeit mit Code usw. ändern. Ich weiß, dass ein solcher Prozess eine PITA mit eingebetteten Geräten sein kann, und ich kann dazu keine Ratschläge geben. Aber ich weiß, dass niemand sie schreiben wird, wenn es schwierig ist, die Tests auszuführen.
Testen Sie, was getestet werden kann
Ich weiß, dass ich hier gegen die gängige Unit-Test-Philosophie verstoße, aber das ist, was ich tue: Schreibe Tests für die Dinge, die einfach zu testen sind. Ich mache mir keine Gedanken über das Verspotten, ich überarbeite es nicht, um es testbar zu machen, und wenn es sich um eine Benutzeroberfläche handelt, habe ich keinen Komponententest. Aber immer mehr meiner Bibliotheksroutinen haben eine.
Ich bin ziemlich erstaunt, welche einfachen Tests dazu neigen, zu finden. Das Pflücken der niedrig hängenden Früchte ist keineswegs nutzlos.
Anders ausgedrückt: Sie würden nicht vorhaben, dieses riesige Haarball-Chaos aufrechtzuerhalten, wenn es kein erfolgreiches Produkt wäre. Ihre derzeitige Qualitätskontrolle ist kein Totalausfall, der ersetzt werden muss. Verwenden Sie Unit-Tests lieber dort, wo sie einfach durchzuführen sind.
(Sie müssen es jedoch erledigen. Lassen Sie sich nicht darauf ein, "alles zu reparieren", was Ihren Erstellungsprozess betrifft.)
Lehren Sie, wie Sie Ihre Codebasis verbessern können
Jede Codebasis mit dieser Historie schreit nach Verbesserungen, das ist sicher. Sie werden jedoch nie alles umgestalten.
Wenn man sich zwei Codeteile mit derselben Funktionalität ansieht, können die meisten Menschen zustimmen, welches unter einem bestimmten Aspekt (Leistung, Lesbarkeit, Wartbarkeit, Testbarkeit, ...) "besser" ist. Die harten Teile sind drei:
Der erste Punkt ist wahrscheinlich der schwierigste und ebenso eine soziale wie eine technische Frage. Aber die anderen Punkte können gelernt werden. Ich kenne keine formalen Kurse, die diesen Ansatz verfolgen, aber vielleicht können Sie etwas intern organisieren: alles, von zwei Jungs, die sich zusammenfinden, bis zu "Workshops", in denen Sie ein böses Stück Code nehmen und darüber diskutieren, wie Sie es verbessern können.
quelle
Das alles hat einen philosophischen Aspekt.
Möchten Sie wirklich getesteten, voll funktionsfähigen und aufgeräumten Code? Ist es IHR Ziel? Profitieren SIE überhaupt davon?
ja, das klingt zunächst total dumm. Aber ehrlich gesagt, wenn Sie nicht der eigentliche Eigentümer des Systems und nicht nur ein Mitarbeiter sind, bedeuten Fehler einfach mehr Arbeit, mehr Arbeit bedeutet mehr Geld. Sie können total glücklich sein, wenn Sie an einem Haarball arbeiten.
Ich vermute hier nur, aber das Risiko, das Sie eingehen, wenn Sie sich diesem großen Kampf stellen, ist wahrscheinlich viel höher als die mögliche Rückzahlung, die Sie erhalten, wenn Sie den Code aufräumen. Wenn Ihnen die sozialen Fähigkeiten fehlen, um dies durchzusetzen, werden Sie nur als Unruhestifter angesehen. Ich habe diese Leute gesehen und ich war auch einer. Aber natürlich ist es ziemlich cool, wenn Sie das durchziehen. Ich wäre beeindruckt.
Aber wenn Sie das Gefühl haben, jetzt zusätzliche Stunden zu verbringen, um ein unordentliches System am Laufen zu halten, glauben Sie wirklich, dass sich dies ändern wird, sobald der Code aufgeräumt und schön wird? Nein. Sobald der Code schön und ordentlich ist, haben die Leute all diese Freizeit, um ihn zum ersten verfügbaren Termin wieder vollständig zu zerstören.
Am Ende ist es das Management, das den Arbeitsplatz schön macht, nicht der Code.
quelle
Ich bin mir nicht sicher, ob es tatsächlich ist oder nicht, aber ich habe hier einen kleinen Rat. Soweit ich weiß, stellen Sie methodische Fragen zur inkrementellen nicht-invasiven Integration von Unit-Tests in riesigen Legacy-Code, wobei viele Stakeholder ihren Sumpf schützen.
Normalerweise besteht der erste Schritt darin, Ihren Testcode unabhängig von allen anderen Codes zu erstellen. Selbst dieser Schritt in langlebigem Legacy-Code ist sehr komplex. Ich schlage vor, Ihren Testcode als dynamische gemeinsam genutzte Bibliothek mit Laufzeitverknüpfung zu erstellen. Auf diese Weise können Sie nur einen kleinen Teil des Codes überarbeiten, der nicht getestet wird, und nicht die gesamte 20K-Datei. Sie können also damit beginnen, Funktion für Funktion abzudecken, ohne alle Verknüpfungsprobleme zu berühren / zu beheben
quelle