Wie testen / ändern Sie nicht getesteten und nicht testbaren Code?

8

In letzter Zeit musste ich Code auf älteren Systemen ändern, wo nicht der gesamte Code Komponententests hat.
Bevor ich die Änderungen durchführe, möchte ich Tests schreiben, aber jede Klasse hat viele Abhängigkeiten und andere Anti-Patterns erzeugt, die das Testen sehr schwierig gemacht haben.
Offensichtlich wollte ich den Code umgestalten, um das Testen zu vereinfachen, die Tests zu schreiben und sie dann zu ändern.
Ist das die Art, wie du es tun würdest? Oder würden Sie viel Zeit damit verbringen, die schwer zu schreibenden Tests zu schreiben, die nach dem Refactoring größtenteils entfernt werden würden?

    
abyx 10.08.2008, 18:49
quelle

4 Antworten

5

Zunächst hier ein großartiger Artikel mit Tipps zum Komponententest . Zweitens fand ich eine großartige Möglichkeit, um zu vermeiden, dass viele Änderungen im alten Code darin bestehen, ihn einfach ein wenig zu überarbeiten, bis man ihn testen kann. Eine einfache Möglichkeit besteht darin, private Mitglieder zu schützen und dann das geschützte Feld zu überschreiben.

Angenommen, Sie haben eine Klasse, die während des Konstruktors Daten aus der Datenbank lädt. In diesem Fall können Sie nicht einfach eine geschützte Methode überschreiben, sondern Sie können die DB-Logik in ein geschütztes Feld extrahieren und dann im Test überschreiben.

%Vor%

wird

%Vor%

und dann sieht dein Test ungefähr so ​​aus:

%Vor%

Das ist ein ziemlich schlechtes Beispiel, weil Sie in diesem Fall DBUnit verwenden könnten, aber ich habe das kürzlich in einem ähnlichen Fall gemacht, weil ich einige Funktionen testen wollte, die nichts mit den geladenen Daten zu tun haben, also sehr effektiv . Ich habe auch herausgefunden, dass das Aufdecken von Mitgliedern in anderen ähnlichen Fällen nützlich ist, in denen ich einige Abhängigkeiten loswerden muss, die lange in einer Klasse waren.

Ich würde diese Lösung jedoch empfehlen, wenn Sie ein Framework schreiben, es sei denn, es macht Ihnen nichts aus, die Mitglieder den Benutzern Ihres Frameworks zugänglich zu machen.

Es ist ein bisschen wie ein Hack, aber ich habe es ziemlich nützlich gefunden.

    
Mike Stone 10.08.2008, 19:22
quelle
3

@valters

Ich stimme Ihrer Aussage nicht zu, dass Tests den Build nicht unterbrechen sollten. Die Tests sollten ein Hinweis darauf sein, dass die Anwendung keine neuen Fehler für die getestete Funktionalität enthält (und ein gefundener Fehler ist ein Hinweis auf einen fehlenden Test).

Wenn Tests den Build nicht unterbrechen, können Sie leicht in die Situation eindringen, in der neuer Code den Build durchbricht, und es ist eine Weile nicht bekannt, obwohl ein Test dies abdeckte. Ein fehlgeschlagener Test sollte eine rote Markierung sein, dass entweder der Test oder der Code repariert werden muss.

Wenn die Tests den Build nicht unterbrechen, wird die Fehlerrate langsam ansteigen und Sie haben keine zuverlässigen Regressionstests mehr.

Wenn es ein Problem mit zu oft abbrechenden Tests gibt, kann dies ein Hinweis darauf sein, dass die Tests zu fragil geschrieben sind (Abhängigkeit von Ressourcen, die sich ändern könnten, wie z. B. die Datenbank ohne DB Unit korrekt zu verwenden) externer Webdienst, der verspottet werden sollte), oder es kann ein Hinweis darauf sein, dass es Entwickler im Team gibt, die den Tests nicht die richtige Aufmerksamkeit schenken.

Ich bin fest davon überzeugt, dass ein fehlerhafter Test so schnell wie möglich behoben werden sollte, genauso wie Sie Code reparieren würden, der nicht so schnell kompiliert werden kann.

    
Mike Stone 10.08.2008 22:55
quelle
0

Ich bin mir nicht sicher, warum Sie sagen sollten, dass Komponententests entfernt werden, sobald das Refactoring abgeschlossen ist. Eigentlich sollte Ihre Unit-Test-Suite nach dem Haupt-Build laufen (Sie können einen separaten "Tests" Build erstellen, der nur die Unit-Tests ausführt, nachdem das Hauptprodukt erstellt wurde). Dann sehen Sie sofort, ob Änderungen an einem Teil die Tests in anderen Subsystemen unterbrechen. Beachten Sie, dass es ein bisschen anders ist, Tests während des Builds auszuführen (wie einige befürworten) - einige begrenzte Tests sind während des Builds nützlich, aber normalerweise ist es unproduktiv, den Build "abzustürzen", nur weil ein Komponententest fehlschlägt.

Wenn Sie Java schreiben (sind wahrscheinlich), schauen Sie sich Ссылка an - kann nützlich sein, um die Kopplung für Testzwecke zu reduzieren.

    
Valters Vingolds 10.08.2008 20:28
quelle
0

Ich habe gelesen, dass ich effektiv mit altem Code arbeite, und ich stimme zu, dass es sehr nützlich ist, um mit "nicht testbarem" Code umzugehen.

Einige Techniken gelten nur für kompilierte Sprachen (ich arbeite an "alten" PHP-Apps), aber ich würde sagen, dass der größte Teil des Buches auf jede Sprache anwendbar ist.

Refactoring-Bücher gehen manchmal davon aus, dass sich der Code vor dem Refactoring in halb-idealem oder "wartungsbewusstem" Zustand befindet, aber die Systeme, an denen ich arbeite, sind weniger als ideal und wurden als Apps für "Lernen wie Sie gehen" entwickelt einige Technologien verwendet (und ich nicht die ersten Entwickler dafür verantwortlich, da ich einer von ihnen bin), so dass es überhaupt keine Tests gibt, und Code ist manchmal chaotisch. Dieses Buch behandelt diese Art von Situation, während andere Refactoring-Bücher normalerweise nicht (gut, nicht in diesem Ausmaß).

Ich sollte erwähnen, dass ich weder vom Herausgeber noch vom Autor dieses Buches Geld bekommen habe;), aber ich fand es sehr interessant, da im Bereich des Legacy-Codes (und insbesondere in meiner Sprache, Französisch) Ressourcen fehlen , aber das ist eine andere Geschichte).

    
Ced-le-pingouin 30.08.2008 16:44
quelle