5 Stimmen

Integrationstests - kann man sie richtig machen?

Ich habe TDD als Entwicklungsstil in den letzten zwei Jahren bei einigen Projekten eingesetzt, aber ich bleibe immer an demselben Punkt hängen: Wie kann ich die Integration der verschiedenen Teile meines Programms testen?

Derzeit schreibe ich einen Testfall pro Klasse (dies ist meine Faustregel: eine "Einheit" ist eine Klasse, und jede Klasse hat einen oder mehrere Testfälle). Ich versuche, Abhängigkeiten mit Hilfe von Mocks und Stubs aufzulösen, und das funktioniert wirklich gut, da jede Klasse unabhängig getestet werden kann. Nach einiger Codierung sind alle wichtigen Klassen getestet. Dann "verdrahte" ich sie mit einem IoC-Container. Und hier stecke ich fest: Wie kann ich testen, ob die Verdrahtung erfolgreich war und die Objekte so interagieren, wie ich es möchte?

Ein Beispiel: Denken Sie an eine Webanwendung. Es gibt eine Controllerklasse, die ein Array von IDs nimmt, ein Repository verwendet, um die Datensätze auf der Grundlage dieser IDs zu holen, dann über die Datensätze iteriert und sie als String in eine Outfile schreibt.

Der Einfachheit halber würde es drei Klassen geben: Controller , Repository , OutfileWriter . Jede von ihnen wird isoliert getestet.

Was ich tun würde, um die "echte" Anwendung zu testen: die http-Anfrage (entweder manuell oder automatisiert) mit einigen IDs aus der Datenbank und dann in das Dateisystem schauen, wenn die Datei geschrieben wurde. Natürlich könnte dieser Prozess automatisiert werden, aber trotzdem: dupliziert das nicht die Testlogik? Ist das, was man einen "Integrationstest" nennt? In einem Buch, das ich kürzlich über Unit-Tests gelesen habe, schien es mir, dass Integrationstests eher ein Anti-Muster sind?

4voto

johnny g Punkte 3483

Meiner Meinung nach - und ich habe keine Literatur, die mir das bestätigt - liegt der Hauptunterschied zwischen unseren verschiedenen Prüfungsformen im Umfang,

  • Unit-Testing ist das Testen isolierter Teile der Funktionalität [typischerweise eine Methode oder zustandsabhängige Klasse].
  • Bei Integrationstests wird die Interaktion von zwei oder mehr abhängigen Teilen getestet [typischerweise ein Dienst und ein Verbraucher oder sogar eine Datenbankverbindung oder eine Verbindung zu einem anderen Remote-Dienst].
  • Systemintegrationstests sind Tests eines Systems von Ende zu Ende [ein Spezialfall von Integrationstests].

Wenn Sie mit Unit-Tests vertraut sind, dürfte es Sie nicht überraschen, dass es so etwas wie einen perfekten oder "magischen" Test nicht gibt. Integrations- und Systemintegrationstests ähneln den Unit-Tests insofern, als es sich um eine Reihe von Tests handelt, mit denen ein bestimmtes Verhalten überprüft werden soll.

Für jeden Test legen Sie den Umfang fest, der dann die Eingabe und die erwartete Ausgabe vorgibt. Anschließend führen Sie den Test aus und werten die tatsächliche mit der erwarteten Ausgabe aus.

In der Praxis haben Sie vielleicht eine gute Vorstellung davon, wie das System funktioniert, so dass das Schreiben typischer positiver und negativer Pfad-Tests für Sie selbstverständlich ist. Bei einer ausreichend komplexen Anwendung ist es jedoch unvernünftig, eine vollständige Abdeckung aller möglichen Szenarien zu erwarten.

Leider bedeutet dies, dass unerwartete Szenarien in den Zyklen der Qualitätssicherung [QA], der Produktionsvorbereitung [PP] und der Produktion [Prod] auftauchen werden. Zu diesem Zeitpunkt sollten Ihre Versuche, diese Szenarien in der Entwicklung zu replizieren, als automatisierte Tests in Ihre Integrations- und Systemintegrationssuites einfließen.

Ich hoffe, das hilft :)


ps: Lieblingsärgernis Nr. 1: Manager oder Entwickler, die Integrations- und Systemintegrationstests als "Unit-Tests" bezeichnen, nur weil nUnit oder MsTest zur Automatisierung verwendet wurde ...

3voto

Péter Török Punkte 111735

Was Sie beschreiben, sind in der Tat Integrationstests (mehr oder weniger). A

Jedes einigermaßen komplizierte Programm ist mehr als die Summe seiner Teile. Deshalb wie gut Sie auch immer die Einheitstests durchführen, Sie haben immer noch keine Ahnung, ob das gesamte System wie erwartet funktionieren wird .

Dafür gibt es mehrere Gründe:

  • Unit-Tests werden in einer isolierten Umgebung durchgeführt, so dass sie nichts darüber aussagen können, wie die Teile des Programms in der Realität zusammenarbeiten
  • der "Unit-Tester-Hut" schränkt den Blick leicht ein, so dass es ganze Klassen von Faktoren gibt, die die Entwickler einfach nicht als etwas erkennen, das getestet werden muss*
  • Selbst wenn dies der Fall ist, gibt es Dinge, die in Unit-Tests nicht vernünftig getestet werden können - wie testen Sie z. B., ob Ihr App-Server unter hoher Last überlebt, oder ob die DB-Verbindung mitten in einer Anfrage zusammenbricht?

* Ein Beispiel, das ich gerade in Luke Hohmanns Buch Beyond Software Architecture gelesen habe: In einer Anwendung, die einen starken Schutz vor Piraterie anwandte, indem sie einen "Schnappschuss" der IDs von HW-Komponenten in der aktuellen Maschine erstellte und pflegte, hatten die Entwickler den Code sehr gut mit Unit-Tests abgedeckt. Dann gelang es der QA, die Anwendung innerhalb von 10 Minuten zum Absturz zu bringen, indem sie sie auf einem Rechner ohne Netzwerkkarte ausprobierte. Wie sich herausstellte, gingen die Entwickler, da sie mit Macs arbeiteten, davon aus, dass der Rechner über eine Netzwerkkarte verfügt, deren MAC-Adresse in den Snapshot aufgenommen werden kann...

0voto

RyBolt Punkte 1724

Was ich tun würde, um die "echte" Anwendung zu testen: die http Anfrage (entweder manuell oder automatisch) mit einigen IDs aus der Datenbank und dann im Dateisystem nachsehen, ob die Datei geschrieben wurde. Natürlich kann dieser Prozess könnte natürlich automatisiert werden, aber trotzdem: Wird dadurch nicht die Testlogik dupliziert?

Vielleicht gibt es doppelten Code, aber es gibt keine doppelten Anstrengungen. Unit-Tests und Integrationstests dienen zwei verschiedenen Zwecken, und normalerweise sind beide Zwecke im SDLC erwünscht. Wenn möglich, sollten Sie den für Unit- und Integrationstests verwendeten Code in einer gemeinsamen Bibliothek zusammenfassen. Ich würde auch versuchen, getrennte Projekte für Ihre Unit-/Integrationstests zu haben, weil Ihre Unit-Tests sollten separat ausgeführt werden (schnell und ohne Abhängigkeiten). Ihre Integrationstests sind spröder und brechen oft, so dass Sie wahrscheinlich eine andere Strategie für die Ausführung/Wartung dieser Tests haben werden.

Nennt man das einen "Integrationstest"? Test" genannt?

Ja, das ist es.

0voto

Gutzofter Punkte 2005

Bei einem Integrationstest müssen Sie, genau wie bei einem Unit-Test, überprüfen, was im Test passiert ist. In Ihrem Beispiel haben Sie eine OutfileWriter Sie benötigen einen Mechanismus, um zu überprüfen, ob die Datei und die Daten in Ordnung sind. Sie möchten dies wirklich automatisieren, so dass Sie vielleicht eine:

Class OutFilevalidator {
    function isCorrect(fName, dataList) {
       // open file read data and
       // validation logic
}

0voto

VoiceOfUnreason Punkte 45380

Lesen Sie "Taming the Beast", eine Präsentation von Markus Clermont und John Thomas über automatisierte Tests von AJAX-Anwendungen. YouTube-Video

Sehr grobe Zusammenfassung eines wichtigen Teils: Sie wollen die kleinstmögliche Testtechnik für eine bestimmte Überprüfung verwenden. Anders ausgedrückt: Sie versuchen, die für die Durchführung aller Tests benötigte Zeit zu minimieren, ohne dabei Informationen zu opfern.

Bei den größeren Tests geht es daher vor allem darum, sicherzustellen, dass die Anschlüsse richtig sind - befindet sich Registerkarte A tatsächlich in Steckplatz A und nicht in Steckplatz B; stimmen beide Komponenten darin überein, dass die Länge in Metern und nicht in Fuß gemessen wird, und so weiter.

Es wird eine Duplizierung der Codepfade geben, die ausgeführt werden, und möglicherweise werden Sie einen Teil des Setup- und Verifizierungscodes wiederverwenden, aber ich würde normalerweise nicht erwarten, dass Ihre Integrationstests das gleiche Maß an kombinatorischer Explosion enthalten, wie es auf Unit-Ebene der Fall wäre.

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