Es ist.
Selbst wenn Sie nur Unit-Tests durchführen, ist es nicht ungewöhnlich, dass mehr Code in den Tests enthalten ist als der tatsächlich getestete Code. Daran ist nichts auszusetzen.
Betrachten Sie einen einfachen Code:
public void SayHello(string personName)
{
if (personName == null) throw new NullArgumentException("personName");
Console.WriteLine("Hello, {0}!", personName);
}
Was wären die Tests? Es gibt mindestens vier einfache Fälle, die hier getestet werden müssen:
Der Name der Person lautet null
. Wird die Ausnahme tatsächlich geworfen? Das sind mindestens drei Zeilen Testcode, die geschrieben werden müssen.
Der Name der Person lautet "Jeff"
. Bekommen wir eine "Hello, Jeff!"
Antwort? Das sind vier Zeilen Testcode.
Der Name der Person ist eine leere Zeichenfolge. Welche Leistung erwarten wir? Was ist die tatsächliche Ausgabe? Nebenfrage: Entspricht es den funktionalen Anforderungen? Das bedeutet weitere vier Codezeilen für den Unit-Test.
Der Name der Person ist kurz genug für eine Zeichenfolge, aber zu lang, um mit "Hello, "
dem Ausrufezeichen kombiniert zu werden . Was passiert? ¹
Dies erfordert viel Testcode. Darüber hinaus erfordern die elementarsten Codeteile häufig Setup-Code, der die für den zu testenden Code erforderlichen Objekte initialisiert, was auch häufig zum Schreiben von Stubs und Mocks usw. führt.
Wenn das Verhältnis sehr groß ist, können Sie in diesem Fall einige Dinge überprüfen:
Gibt es Code-Duplikationen zwischen den Tests? Die Tatsache, dass es sich um Testcode handelt, bedeutet nicht, dass der Code zwischen ähnlichen Tests dupliziert (kopiert und eingefügt) werden sollte. Eine solche Duplizierung erschwert die Wartung dieser Tests.
Gibt es redundante Tests? Als Faustregel gilt: Wenn Sie einen Komponententest entfernen, sollte sich die Zweigabdeckung verringern. Wenn dies nicht der Fall ist, wird möglicherweise angezeigt, dass der Test nicht benötigt wird, da die Pfade bereits von anderen Tests abgedeckt werden.
Testen Sie nur den Code, den Sie testen sollten? Es wird nicht erwartet, dass Sie das zugrunde liegende Framework der Bibliotheken von Drittanbietern testen , sondern ausschließlich den Code des Projekts selbst.
Mit Rauch-, System- und Integrationstests, Funktions- und Abnahmetests sowie Belastungs- und Belastungstests fügen Sie noch mehr Testcode hinzu, sodass Sie sich keine Sorgen machen sollten, vier oder fünf LOC-Tests für jeden LOC-Code zu haben.
Ein Hinweis zu TDD
Wenn Sie sich Sorgen über die Zeit machen, die zum Testen Ihres Codes erforderlich ist, liegt es möglicherweise an Ihnen, dass Sie etwas falsch machen. Das heißt, dass der Code zuerst und später getestet wird. In diesem Fall kann TDD helfen, indem es Sie ermutigt, in Iterationen von 15 bis 45 Sekunden zwischen Code und Tests zu wechseln. Laut den Befürwortern von TDD wird der Entwicklungsprozess beschleunigt, indem sowohl die Anzahl der erforderlichen Tests als auch, was noch wichtiger ist, der Umfang des Geschäftscodes, der zum Testen geschrieben und insbesondere neu geschrieben werden muss, verringert wird .
¹ Sei n sein die maximale Länge eines Strings . Wir können SayHello
eine Zeichenkette der Länge n - 1 aufrufen und als Referenz übergeben, was gut funktionieren sollte. Bei Console.WriteLine
Schritt sollte die Formatierung nun mit einer Zeichenfolge der Länge n + 8 enden , was zu einer Ausnahme führt. Möglicherweise führt aufgrund der Speicherbeschränkungen sogar eine Zeichenfolge mit n / 2 Zeichen zu einer Ausnahme. Die Frage, die man sich stellen sollte, ist, ob dieser vierte Test ein Komponententest ist (er sieht aus wie einer, kann jedoch im Vergleich zu durchschnittlichen Komponententests eine viel größere Auswirkung auf die Ressourcen haben) und ob er den tatsächlichen Code oder das zugrunde liegende Framework testet.