Integrationstests, aber wie viel?

8

Eine kürzliche Debatte in meinem Team hat mich gewundert. Das Grundthema ist, wie viel und was wir mit Funktions- / Integrationstests abdecken sollen (sicher, sie sind nicht gleich, aber das Beispiel ist Dummy, wo es keine Rolle spielt).

Angenommen, Sie haben eine "Controller" -Klasse wie:

public class SomeController {
    @Autowired Validator val;
    @Autowired DataAccess da;
    @Autowired SomeTransformer tr;
    @Autowired Calculator calc;

    public boolean doCheck(Input input) {
        if (val.validate(input)) {
             return false;
        }

        List<Stuff> stuffs = da.loadStuffs(input);
        if (stuffs.isEmpty()) {
             return false;
        }

        BusinessStuff businessStuff = tr.transform(stuffs);
        if (null == businessStuff) {
            return false;
        }

       return calc.check(businessStuff);
    }
}

Wir brauchen mit Sicherheit viele Unit-Tests (z. B. wenn die Validierung fehlschlägt oder keine Daten in der Datenbank vorhanden sind, ...), das kommt nicht in Frage.

Unser Hauptproblem und darüber können wir uns nicht einigen, wie viele Integrationstests es abdecken sollen :-)

Ich bin auf der Seite, dass wir weniger Integrationstests anstreben werden (Testpyramide). Was ich davon abdecken würde, ist nur ein einziger glücklich-unglücklicher Pfad, auf dem die Ausführung von der letzten Zeile zurückkehrt, nur um zu sehen, ob ich diese Sachen zusammenstelle, wird sie nicht explodieren.

Das Problem ist, dass es nicht so einfach ist zu sagen, warum der Testergebnis falsch war, und dass sich einige der Jungs darüber unwohl fühlen (z. B. wenn wir nur den Rückgabewert überprüfen, ist es verborgen, dass der Test grün ist weil jemand die Validierung geändert hat und sie false zurückgibt). Sicher, ja, wir können alle Fälle abdecken, aber das wäre imho ein schwerer Overkill.

Hat jemand eine gute Faustregel für diese Art von Problemen? Oder eine Empfehlung? Lesen? Sich unterhalten? Blogeintrag? Irgendwas zum Thema?

Vielen Dank im Voraus!

PS: Sry für das hässliche Beispiel, aber es ist ziemlich schwierig, einen bestimmten Codeteil in ein Beispiel zu übersetzen. Ja, man kann darüber streiten, Ausnahmen auszulösen / einen anderen Rückgabetyp zu verwenden / etc. aber unsere Hand ist aufgrund externer Abhängigkeiten mehr oder weniger gebunden.

PS2: Ich habe dieses Thema von SO hierher verschoben (ursprüngliche Frage, in der Warteschleife markiert )

rlegendi
quelle

Antworten:

6

Es gibt eine Denkschule, die den Wert von Integrationstests ernsthaft in Frage stellt .

Ich vermute, dass Sie hier ein breites Spektrum an Antworten erhalten, aber meiner Meinung nach sollten Sie sie nur verwenden, wenn sie einen klaren Wert liefern.

Erstens sollten Sie so viele Komponententests wie möglich schreiben, da a) sie billig sind und b) sie möglicherweise die einzigen Tests sind, die auf dem Build-Server ausgeführt werden (falls Sie einen haben).

Es ist verlockend, clientseitige Tests zu schreiben, um die Datenbank oder eine andere Ebene zu überprüfen, aber diese sollten nach Möglichkeit auf der entsprechenden Ebene stattfinden, anstatt einen Integrationstest zu erfinden. Dies kann natürlich einige Grundlagen in Form von Schnittstellen usw. erfordern, damit Spott und dergleichen funktionieren.

Berücksichtigen Sie auch den Umfang Ihrer Tests. Wenn Sie lediglich einen Integrationstest schreiben, um zu beschreiben, was ohnehin passiert, wenn Ihre Suite ausgeführt wird, oder um einen Rauchtest zu duplizieren, hat dies nur einen begrenzten Wert. Überlegen Sie auch, ob mehr Protokollierung an relevanten Stellen eine bessere Option wäre, als eine dunkle Nachricht von einem Dutzend miteinander verbundener Komponenten zu erhalten und diese zu verfolgen.

Angenommen, Sie haben beschlossen, einige zu schreiben, müssen Sie darüber nachdenken, wann sie ausgeführt werden. Wenn sie ein böses Problem feststellen können, ist das großartig, aber das wird ziemlich sinnlos, wenn Entwickler nie daran denken, sie auszuführen.

Schließlich sind Integrationstests ein völlig ungeeigneter Ersatz für Rauch- und Benutzertests. Wenn Sie sich überhaupt mit ihnen beschäftigen, sollten sie einen kleinen Teil eines gut konzipierten Testprozesses bilden.

Robbie Dee
quelle
4
Nur ein Kommentar: Beachten Sie, dass es umgekehrt eine Denkschule gibt, die den Wert von Unit-Tests ernsthaft in Frage stellt (DHH behauptet, TDD in Frage zu stellen, aber wenn Sie seinen Beitrag lesen, stellt er auch Unit-Tests in Frage). Um ehrlich zu sein, finde ich Dinge, die beiden extremistischen Denkschulen zustimmen und nicht zustimmen :)
Andres F.
1
Ein Großteil des Dogmas um TDD besteht darin, nichts zu schreiben, was kein erfahrener Entwickler durch YAGNI kennt ...
Robbie Dee
4
Ihre Antwort ist in Ordnung (+1), der von Ihnen zitierte Artikel hat jedoch das Problem, dass der Autor den Eindruck erweckt, nur weil Integrationstests für seinen Fall nicht funktionierten, sie für niemanden anderen funktionieren. In unserem Team verwenden wir hier seit mehr als 10 Jahren Integrationstests für unser Produkt in der Praxis. Sie haben uns daran gehindert, viele Male schwerwiegende Fehler zu implementieren. Daher denke ich, dass es tatsächlich möglich ist, Integrationstests zu schreiben, die einen hohen Wert liefern.
Doc Brown
Der Autor schreibt auch in einem Kommentar "Integrierte Tests (nicht" Integrationstests "!) [...]" - Ich bin mir über den Unterschied nicht sicher, aber es scheint mir, dass es eine Menge Nuancen gibt, ob ein Integrationstest ist nützlich oder gut.
Carson Myers
Nach meiner Erfahrung liefern nur Integrationstests wirklich Wert. Unit-Tests, insbesondere solche, die Spott verwenden, sind mehr Mühe als sie wert sind. In meinem aktuellen Projekt haben wir beispielsweise 650 JUnit-basierte Integrationstests, die bei jedem Commit auf einem Jenkins-Server ausgeführt werden, wobei der vollständige Build weniger als 10 Minuten dauert. Natürlich führen wir auch Tests mit unseren IDEs durch, während wir TDD durchführen. Wir sehen keine Notwendigkeit für eine zusätzliche Reihe von Unit-Tests - dies würde viel mehr Aufwand bedeuten, ohne dass ein offensichtlicher Gewinn erzielt werden könnte. Vielleicht ist der Grund, warum einige Entwickler Integrationstests vermeiden, einfach, dass sie es nicht wirklich versucht haben?
Rogério
8

Im Gegensatz zu dieser Antwort finde ich das Testen auf verschiedenen Ebenen ein wichtiger Bestandteil des Softwaretestprozesses. Einheit, Funktion, Integration, Rauch, Akzeptanz und andere Arten von Tests testen verschiedene Dinge, und je mehr desto besser.

Und wenn Sie es schaffen, sie zu automatisieren, können sie als Job Ihrer kontinuierlichen Integration ausgeführt werden (wie Jenkins). Niemand muss sie ausführen, um zu sehen, ob sie kaputt sind, da jeder sehen kann, ob Tests fehlgeschlagen sind.

In meinen Integrationstests gehe ich nicht auf Details ein - Details und Eckfälle gelten für Unit-Tests. Was ich teste, ist nur die Hauptfunktionalität, bei der alle korrekten Parameter übergeben werden. Das heißt, in Ihrem Beispiel würde ich in den Integrationstests keine falschen Pfade abdecken.

BЈовић
quelle
1
1 Ja, wenn Sie können Integrationstests in dem Build tun dann um so besser , aber dies kann ein bedeutendes Unternehmen in betrieblicher Ebene Lösungen sein.
Robbie Dee