Sie benötigen ein C # -Beispiel für unbeabsichtigte Konsequenzen

8

Ich stelle eine Präsentation über die Vorteile von Unit Testing zusammen und möchte ein einfaches Beispiel für unbeabsichtigte Konsequenzen: Code in einer Klasse ändern, die Funktionalität in einer anderen Klasse durchbricht.

Kann jemand ein einfaches, leicht zu erklärendes Beispiel vorschlagen?

Mein Plan ist, Komponententests um diese Funktionalität zu schreiben, um zu zeigen, dass wir wissen, dass wir etwas kaputt gemacht haben, indem wir den Test sofort ausgeführt haben.

    
dgiard 12.08.2010, 21:45
quelle

3 Antworten

12

Ein etwas einfacheres und damit vielleicht übersichtlicheres Beispiel ist:

%Vor%

Wenn GetServerAddress Änderungen an einem Array zurückgibt:

%Vor%

Die Ausgabe von DoSomethingWithServer wird etwas anders sein, aber es wird alles noch kompilieren, was zu einem noch subtileren Fehler führt.

Die erste (Nicht-Array-) Version wird Server address is: 127.0.0.1 ausgeben und die zweite wird Server address is: System.String[] drucken, das ist etwas, das ich auch im Produktionscode gesehen habe. Unnötig zu sagen, dass es nicht mehr da ist!

    
Rob 12.08.2010, 22:02
quelle
8

Hier ist ein Beispiel:

%Vor%

Ändern Sie GetData() , um eine List<Something> zurückzugeben, und Consumer wird unterbrochen.

Dies könnte etwas künstlich gesehen werden, aber ich habe ähnliche Probleme in echtem Code gesehen.

    
SLaks 12.08.2010 21:53
quelle
4

Angenommen, Sie haben eine Methode, die:

%Vor%

Mit verschiedenen Implementierungen verwendet werden. Einer von ihnen wird verwendet in:

%Vor%

Nun, nichts davon ist besonders seltsam. Wir gehen nicht von einer bestimmten Implementierung von IEnumerable aus. In der Tat wird dies für Arrays und sehr viele häufig verwendete Sammlungen funktionieren (ich denke nicht an eine in System.Collections.Generic, die nicht von der Spitze meines Kopfes übereinstimmt). Wir haben nur die normalen Methoden und die normalen Erweiterungsmethoden verwendet. Es ist nicht einmal ungewöhnlich, einen optimierten Fall für Einzelposten-Sammlungen zu haben. Wir könnten zum Beispiel die Liste ändern, um ein Array zu sein, oder vielleicht ein HashSet (um Dubletten automatisch zu entfernen), oder eine LinkedList oder ein paar andere Dinge, und es wird weiter funktionieren.

Obwohl wir nicht von einer bestimmten Implementierung abhängig sind, hängen wir von einer bestimmten Funktion ab, speziell von der Fähigkeit, zurückzuspulen ( Count() ruft entweder ICollection.Count auf oder zählt durch das Enumerable, danach den Namen - Überprüfung wird stattfinden.

Jemand sieht jedoch die Ergebnisse-Eigenschaft und denkt "hmm, das ist ein bisschen verschwenderisch". Sie ersetzen es durch:

%Vor%

Das ist wieder völlig in Ordnung und wird in vielen Fällen tatsächlich zu einer erheblichen Leistungssteigerung führen. Wenn CheckNames in den unmittelbaren "Tests" des betreffenden Coders nicht getroffen wird (möglicherweise wird es in vielen Codepfaden nicht gefunden), dann ist die Tatsache, dass CheckNames einen Fehler liefert (und möglicherweise ein falsches Ergebnis zurückgibt) der Fall von mehr als 1 Namen, der noch schlimmer sein kann, wenn es ein Sicherheitsrisiko eröffnet).

Jeder Komponententest, der auf CheckNames mit mehr als null Ergebnissen trifft, fängt ihn jedoch ein.

Übrigens ist eine vergleichbare (wenn auch kompliziertere) Änderung ein Grund für eine Abwärtskompatibilität in NPGSQL. Nicht ganz so einfach, als nur eine List.Add () mit einer Rendite zu ersetzen, aber eine Änderung an der Arbeitsweise von ExecuteReader ergab eine vergleichbare Änderung von O (n) zu O (1), um das erste Ergebnis zu erhalten. Zuvor erlaubte NpgsqlConnection den Benutzern jedoch, einen anderen Reader von einer Verbindung zu erhalten, während der erste noch offen war, und danach nicht. Die Dokumentation für IDbConnection sagt, dass Sie dies nicht tun sollten, aber das bedeutet nicht, dass es keinen laufenden Code gab. Glücklicherweise war ein solcher Teil des laufenden Codes ein NUnit-Test und eine Rückwärtskompatibilitätsfunktion, die hinzugefügt wurde, um zu ermöglichen, dass dieser Code mit nur einer Konfigurationsänderung weiter funktioniert.

    
Jon Hanna 12.08.2010 23:18
quelle

Tags und Links