Wo soll ich die Grenze zwischen Unit-Tests und Integrationstests ziehen? Sollten sie getrennt sein?


11

Ich habe ein kleines MVC-Framework, an dem ich gearbeitet habe. Die Codebasis ist definitiv nicht groß, aber es sind nicht mehr nur ein paar Klassen. Ich habe mich schließlich entschlossen, den Sprung zu wagen und Tests dafür zu schreiben (ja, ich weiß, ich hätte das die ganze Zeit tun sollen, aber die API war bis jetzt super instabil).

Mein Plan ist es jedenfalls, das Testen extrem einfach zu machen, einschließlich Integrationstests. Ein beispielhafter Integrationstest würde in diese Richtung gehen:

Gefälschtes HTTP-Anforderungsobjekt -> MVC-Framework -> HTTP-Antwortobjekt -> Überprüfen Sie, ob die Antwort korrekt ist

Da dies alles ohne Status oder spezielle Tools (Browser-Automatisierung usw.) möglich ist, könnte ich dies mit regulären Unit-Test-Frameworks (ich verwende NUnit) problemlos durchführen.

Nun die große Frage. Wo genau soll ich die Grenze zwischen Unit-Tests und Integrationstests ziehen? Sollte ich jeweils nur eine Klasse (so oft wie möglich) mit Unit-Tests testen? Sollten Integrationstests auch im selben Testprojekt wie mein Unit-Test-Projekt platziert werden?


Beim Integrationstest werden mehrere tatsächliche Implementierungen Ihrer Komponenten zusammen getestet (tatsächliche Implementierungen bedeuten keine Verspottungen).
Kemoda

1
Diese Frage bezieht sich auf Tests und Qualitätssicherung. Daher würde ich vorschlagen, es auf die entsprechende Site SQA auf Stack Exchange ( sqa.stackexchange.com ) zu
migrieren

@dzieciou wusste nicht einmal, dass es das gibt!
Earlz

Antworten:


19

Integration vs. Unit-Tests

Sie sollten Ihre Komponententests und Ihre Integrationstests vollständig getrennt halten. Ihre Komponententests sollten nur eine Sache und eine Sache testen und den Rest Ihres Systems vollständig isolieren. Eine Einheit ist lose definiert, läuft jedoch normalerweise auf eine Methode oder eine Funktion hinaus.

Es ist sinnvoll, Tests für jede Einheit durchzuführen, damit Sie wissen, dass ihre Algorithmen korrekt implementiert sind und Sie sofort wissen, was wo schief gelaufen ist, wenn die Implementierung fehlerhaft ist.

Da Sie während des Unit-Tests vollständig isoliert testen, verwenden Sie Stub- und Mock-Objekte, um sich wie der Rest Ihrer Anwendung zu verhalten. Hier kommen Integrationstests ins Spiel. Das isolierte Testen aller Einheiten ist großartig, aber Sie müssen wissen, ob die Einheiten tatsächlich zusammenarbeiten.

Dies bedeutet zu wissen, ob ein Modell tatsächlich in einer Datenbank gespeichert ist oder ob tatsächlich eine Warnung ausgegeben wird, nachdem Algorithmus X fehlgeschlagen ist.

Testgetriebene Entwicklung

Wenn Sie einen Schritt zurücktreten und sich Test Driven Development (TDD) ansehen, müssen Sie einige Dinge berücksichtigen.

  1. Sie schreiben Ihren Komponententest, bevor Sie den Code schreiben, der ihn bestanden hat.
  2. Sie bestehen den Test und schreiben gerade genug Code, um dies zu erreichen.
  3. Nachdem der Test bestanden wurde, ist es Zeit, einen Schritt zurückzutreten. Gibt es etwas zu überarbeiten, wenn diese neue Funktionalität vorhanden ist? Sie können dies sicher tun, da alles durch Tests abgedeckt ist.

Integration zuerst gegen Integration zuletzt

Integrationstests passen auf zwei Arten in diesen TDD-Zyklus. Ich kenne Leute, die sie gerne vorher schreiben. Sie nennen einen Integrationstest einen End-to-End-Test und definieren einen End-to-End-Test als einen Test, der den gesamten Pfad eines Anwendungsfalls vollständig testet (denken Sie daran, eine Anwendung einzurichten, sie zu booten, zu einem Controller zu gehen, sie auszuführen). Überprüfung auf Ergebnis, Ausgabe usw.). Dann beginnen sie mit ihrem ersten Komponententest, lassen ihn bestehen, fügen einen zweiten hinzu, bestehen ihn usw. Langsam bestehen auch immer mehr Teile des Integrationstests, bis die Funktion abgeschlossen ist.

Der andere Stil besteht darin, einen Feature-Unit-Test nach dem anderen zu erstellen und anschließend die Integrationstests hinzuzufügen, die als notwendig erachtet werden. Der große Unterschied zwischen diesen beiden besteht darin, dass Sie beim Integrationstest zunächst über das Design einer Anwendung nachdenken müssen. Diese Art widerspricht der Annahme, dass es bei TDD sowohl um das Anwendungsdesign als auch um das Testen geht.

Praktische Aspekte

Bei mir haben wir alle unsere Tests im selben Projekt. Es gibt jedoch verschiedene Gruppen. Das Tool für die kontinuierliche Integration führt zuerst die als Komponententests gekennzeichneten Tests aus. Nur wenn diese erfolgreich sind, werden auch die langsameren Integrationstests ausgeführt (weil sie echte Anforderungen stellen, echte Datenbanken verwenden usw.).

Normalerweise verwenden wir übrigens eine Testdatei für eine Klasse.

Vorgeschlagene Literatur

  1. Wachsende objektorientierte Software, die von Tests geleitet wird Dieses Buch ist ein äußerst gutes Beispiel für die erste Methodik des Integrationstests
  2. Die Kunst des Unit-Tests mit Beispielen in dot.net Über Unit-Tests mit Beispielen in dot.net: D Sehr gutes Buch über die Prinzipien des Unit-Tests.
  3. Robert C. Martin über TDD (kostenlose Artikel): Lesen Sie auch die ersten beiden Artikel, die er dort verlinkt hat.

2

Was bei jeder Teststrategie wichtig ist, ist die Testabdeckung - dh zu zeigen, dass alle Funktionen getestet werden.

Ich allgemein, und wenn Sie keine besonderen gegenteiligen Anforderungen haben (z. B. DO178 Level A, IEC61508 SIL 4 usw.), die in Ihrer Situation nicht der Fall zu sein scheinen, können Sie dann die volle Funktion der Klasse oder eines Moduls testen (und Zeigen Sie auf Systemebene, dass das Testen auf Systemebene ausreichend ist. Und so weiter runter. Unit-Tests sind nur erforderlich, wenn Sie die Tests nicht weiter oben behandelt haben.

Wo genau soll ich die Grenze zwischen Unit-Tests und Integrationstests ziehen?

Da Intergrationstests normalerweise einfacher, schneller und billiger sind, ziehen Sie die Grenze so weit wie möglich ...

Sollte ich jeweils nur eine Klasse (so oft wie möglich) mit Unit-Tests testen?

Dies hängt wiederum vom Umfang ab. Per Definition testet ein Komponententest eine einzelne Einheit. Wenn Sie jedoch ein vollständiges Modul auf einmal vollständig testen können, tun Sie dies, wenn Sie dies wünschen. Sie erfüllen tatsächlich mehrere Komponententests mit einem Treffer.

Sollten Integrationstests auch im selben Testprojekt wie mein Unit-Test-Projekt platziert werden?

Kein grundlegender Grund, warum nicht ... es sei denn, der Test auf höherer Ebene wird von einem unabhängigen Tester durchgeführt. Zu diesem Zeitpunkt sollten Sie nur eine ausführbare und minimale Instrumentierung ausgeben.


2
Ich sehe nicht ein, wie Integrationstests einfacher, schneller oder billiger sind. Für mich ist es das Gegenteil von allen 3. Und Integrationstests sind normalerweise spröder als Unit-Tests
Earlz

0

Wenn ich kleine Projekte habe, füge ich einfach alle Tests in dasselbe Projekt ein. Da ein größeres Projekt diese Aufteilung haben würde, stelle ich nur sicher, dass es möglich wäre, sie auseinander zu ziehen, falls es notwendig sein sollte.

Bei Unit-Tests teste ich normalerweise nur eine Klasse (SUT) in einer Datei.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.