5 Stimmen

Wie viel sollte jeder Einheitstest testen?

Wie viel sollte jeder meiner Unit-Tests untersuchen? Ich habe zum Beispiel diesen Test

[TestMethod]
public void IndexReturnsAView()
{
    IActivityRepository repository = GetPopulatedRepository();
    ActivityController activityController = GetActivityController(repository);
    ActionResult result = activityController.Index();
    Assert.IsInstanceOfType(result, typeof(ViewResult));
}

und auch

[TestMethod]
public void IndexReturnsAViewWithAListOfActivitiesInModelData()
{
    IActivityRepository repository = GetPopulatedRepository();
    ActivityController activityController = GetActivityController(repository);
    ViewResult result = activityController.Index() as ViewResult;
    Assert.IsInstanceOfType(result.ViewData.Model, typeof(List<Activity>));
}

Offensichtlich, wenn der erste Test fehlschlägt, dann wird auch der zweite Test so sollten diese beiden in einen Test mit zwei Asserts kombiniert werden? Meiner Meinung nach lassen sich die Ursachen von Fehlern umso schneller finden, je granularer die Tests sind und je weniger jeder Test überprüft. Es gibt jedoch einen Overhead bei einer großen Anzahl von sehr kleinen Tests, der bei der Ausführung aller Tests Zeit kosten kann.

12voto

Orion Edwards Punkte 117361

Ich würde empfehlen, sie so weit wie möglich aufzuschlüsseln.

Dafür gibt es viele Gründe, die wichtigsten sind meiner Meinung nach:

  • Wenn Wenn einer Ihrer Tests fehlschlägt, wollen Sie so schnell und sicher wie möglich herausfinden, was genau schief gelaufen ist. Der beste Weg, dies zu erreichen, ist, dass jede Testmethode nur eine einzige Sache testet.

  • Jede Prüfung muss mit einem Neuanfang beginnen. Wenn Sie das Repository einmal erstellen und es dann in 2 oder mehr Tests verwenden, besteht eine implizite Abhängigkeit von der Reihenfolge dieser Tests. Angenommen, Test1 fügt ein Objekt zum Repository hinzu, vergisst aber, es zu löschen. Das Verhalten von Test2 wird nun anders sein und möglicherweise dazu führen, dass Ihr Test fehlschlägt. Die einzige Ausnahme hiervon sind unveränderliche Daten.

Was Ihre Bedenken bezüglich der Geschwindigkeit angeht, würde ich mir keine Sorgen machen. Für reines Code-Crunching wie dieses, ist .NET sehr und Sie werden den Unterschied nicht bemerken. Sobald Sie aus dem Code-Crunching herauskommen und sich mit Dingen wie Datenbanken beschäftigen, werden Sie die Leistungsprobleme spüren, aber sobald Sie das tun, stoßen Sie auf die oben beschriebenen Probleme mit der "reinen Weste", also müssen Sie vielleicht einfach damit leben (oder so viele Daten wie möglich unveränderlich machen).

Ich wünsche Ihnen viel Erfolg bei Ihren Tests.

3voto

laalto Punkte 143902

Je feinkörniger, desto besser. Wenn eine Assert in einem Testfall fehlschlägt, wird der Testfall nicht weiter ausgeführt. Die letzten Teile des Falles könnten möglicherweise andere Fehler aufdecken.

Wenn zwischen Testfällen gemeinsamer Code verwendet wird, verwenden Sie Setup-/Teardown-Funktionen, um sich darum zu kümmern, ohne sich zu sehr zu wiederholen. Der Zeitaufwand ist oft vernachlässigbar. Wenn das Setup/Teardown zu viel Zeit in Anspruch nimmt, handelt es sich wahrscheinlich nicht um Unit-Tests, sondern um automatisierte Tests auf einer höheren Ebene. Unit-Tests sollten idealerweise keine Abhängigkeiten von Dateisystem, Netzwerk, Datenbank usw. haben.

2voto

Yishai Punkte 87548

Ich denke, die "Standard"-Antwort ist, dass es so weit kommen sollte, dass, wenn ein Fehler im Code auftritt, dieser einen Test abbricht, aber keine anderen Fehler verdeckt (die anderen Tests nicht anhält), wenn dieser eine Test fehlschlägt. Jeder Test testet eine Sache und zwei Tests testen nicht dieselbe Sache. Das ist ein Ideal, das nicht immer erreicht werden kann. Nennen Sie es Anleitung.

Das heißt, es ist wirklich eine Kunst. Ich würde Leistungsfragen zunächst beiseite lassen und mich mehr auf die Wartbarkeit konzentrieren. Dort gibt es zweieinhalb bis drei Zeilen mit Duplikaten. Wenn sich das Design ändert, wird das schwer zu pflegen sein. Die Duplizierung an sich kann in diesem Fall durch eine Setup-Methode und ein Feld in der Klasse gelöst werden, aber die Hauptsorge gilt der Wartbarkeit.

Die Tests sollten klein genug sein, um wartbar zu sein, leicht zu verstehen, und etwas, das es anderen (oder Ihnen nach einiger Zeit) ermöglicht, zu verstehen, was der Code tut, und in der Lage zu sein, die Tests zu warten.

0voto

Martin P. Hellwig Punkte 672

Ein Unit-Test sollte genau das testen, was in Ihrem technischen Entwurf im Hinblick auf den funktionalen Entwurf beschrieben ist.

0voto

topchef Punkte 17965

Der Ansatz, wie viel ein Test testet, ist definitiv etwas, das Sie im Voraus entscheiden und an das Sie sich halten müssen. Ich glaube nicht, dass jeder einheitlich den gleichen Ansatz verfolgen sollte, da verschiedene Teams und/oder Projekte unterschiedliche Prioritäten in Bezug auf Programmierung, Leistung, Fehlerbehebung, Testinfrastruktur usw. haben. Aber eine konsequente Vorgehensweise ist immer hilfreich:

  1. Probleme schneller erkennen, da Sie wissen im Voraus, wie tief Sie graben müssen;
  2. weniger Zeit für die Erstellung von Ihre Tests;
  3. den gleichen Satz verwenden von Testhelferklassen bei der Tests zu implementieren.
  4. Tests schnell genug durchführen: nicht zu schnell und nicht zu langsam.
  5. Organisation von Tests (Suiten, Pakete, usw.)

Wenn Sie entscheiden, dass die Leistung wichtiger ist, implementieren Sie umfangreichere Tests mit mehr Validierungen/Asserttions. Wenn Sie beschließen, dass die Fehlersuche von größter Bedeutung ist, dann isolieren Sie Ihre Tests so weit wie nötig. Ich kann nicht erkennen, warum dicke und gut strukturierte Tests fehlerhaft sein sollen. Solche Tests würden dieselbe Aufgabe erfüllen wie eine größere Anzahl dünnerer Tests, und zwar genauso gut.

Natürlich muss sich jeder Test auf eine bestimmte Funktion/ein bestimmtes Merkmal konzentrieren, aber das ist nicht wirklich das Thema dieses Threads.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X