Integrationstest pro Schicht ist eine gute Übung?

8

Ich habe eine Anwendung, die spring-mvc verwendet, im Grunde haben wir eine Präsentationsschicht (Controller), Service-Schicht (Geschäftseinheiten, Helfer), Integrationsebene und Datenzugriffsebene (jdbc / jpa-Repositories), die wir sicherstellen wollen Das Testen, dass die zukünftige Ergänzung des Codes nichts bricht, was vorher funktionierte, verwenden wir Unit-Testing (Mockito) und Integrationstests (Federtest, Federtest-MVC).

Unit Testing wird pro Klasse / Komponente durchgeführt, im Grunde haben wir versucht, eine gute Abdeckung für die eingehenden Eingänge und mögliche Flüsse innerhalb dieser Komponenten und diese Aktion funktioniert gut, haben hier keine Zweifel, da Unit-Test ist, um sicherzustellen, dass die Einheiten funktionieren wie erwartet.

Integrationstest ist eine andere Geschichte und sehr umstritten, denn wir verwenden manchmal die gleichen Szenarien, die wir bei der Entwicklung unserer Komponententests verwenden, aber das gesamte System unter Verwendung einer echten Plattform usw. verfügbar, aber ich habe Zweifel am Besten Praktiken hier.

  1. Da wir einen Controller haben, Service, Datenschicht Ein Ansatz wird eine IT pro Schicht gemacht, Beispiel haben wir UserService-Klasse, wir haben UserServiceTest, der die Unit-Test und UserServiceIT sein wird, aber Wartbarkeit ist nicht ideal, Ich fühle manchmal, dass wir dasselbe Testszenario wiederholen, aber jetzt das reale System verwenden. Ist diese Praxis sinnvoll oder in welchen Szenarien sinnvoll? Wenn wir bereits 100% Testabdeckung in der Klasse mit Komponententests haben, warum wir IT für diese benötigen, scheint das nur zu sein, um sicherzustellen, dass die reale Komponente gestartet wird?, Sinn macht es, alle die gleichen Szenarien zu haben oder welche ist ein gutes Entscheidungskriterium?

  2. Ein anderer Ansatz besteht darin, mit den wichtigsten Testfällen über den Integrationstest zu gehen, aber nur von der Controller-Schicht, was bedeutet, dass die REST-Dienste aufgerufen werden und die JSON-Ausgabe überprüft wird. Das ist genug?, Müssen wir nicht mehr Dinge in den anderen Ebenen verifizieren? Ich weiß, die echte REST API zu nennen, die unter allen Schichten (Controller, Service, Dao) verwendet wird, aber das ist genug? Einige Überlegung werden Sie hier sagen?

  3. Wenn wir eine Helferklasse haben, ist es nicht sinnvoll, Einheit und IT zu haben, so wie die meisten Methoden für nur einen Zweck. Ich denke, Unit Testing wird hier ausreichen, denkst du das Gleiche ?.

  4. Einige Klassen in der Datenschicht könnten Criteria API verwenden, QueryDSL für diejenigen, die ich mit IT benutze, da das Testen der Einheit in einigen Fällen extrem schwierig ist. Dies ist eine gültige Begründung?

Ich versuche, den besten Weg zu finden, Tipps und Praktiken, die die Aufgabe, die Systemintegrität zu gewährleisten, zu einem echten und wertvollen Prozess machen, der die Wartbarkeit dieser Dinge berücksichtigt.

    
Koitoer 06.10.2015, 16:20
quelle

3 Antworten

6

Sie berühren die gesamte Teststrategie, die für Ihre Anwendung erforderlich ist. Beim Testen geht es nicht nur um Coverage und Layer. Als Beispiel:

  

Wir möchten sicherstellen, dass wir mit dem Testen testen, dass die zukünftige Ergänzung des Codes nichts bricht, was vorher funktionierte. Dazu verwenden wir Komponententests (Mockito) und Integrationstests (Federtest, Federtest-MVC). .

So unterstützen Sie Regressionstests , was ein Typ ist. Wenn wir uns die (detaillierte) Testpyramide anschauen

Es ist leicht zu sehen, dass die Integrationstests eine gute Portion einnehmen (empfohlen 5-15%). Die Integration erfolgt übergreifend, aber auch übergreifend. Es ist normal, dass Ihre Geschäftskomponenten in derselben Schicht leben, Sie müssen jedoch sicherstellen, dass sie auch wie erwartet miteinander funktionieren. mSOA wird Sie dazu bringen, solche umfangreichen Schnittstellen-Integrationstests zu unterstützen.

Ich stimme Ihnen in diesem Punkt zu

  

Integrationstest ist eine andere Geschichte und sehr umstritten

Einige Experten schlagen sogar vor, nur Unit-Tests und die GUI E2E zu behalten > Einsen. IMHO gibt es keine strengen Best Practices - nur gute. Wenn Sie mit den Kompromissen zufrieden sind, verwenden Sie, was immer Ihrem Fall entspricht.

  

Ich fühle manchmal, dass wir das gleiche Testszenario wiederholen, aber jetzt das reale System verwenden. Ist diese Praxis wirklich sinnvoll oder in welchen Szenarien sinnvoll? Wenn wir bereits 100% Testabdeckung in der Klasse mit Komponententests haben, warum wir IT für diese benötigen, scheint das nur zu sein, um sicherzustellen, dass die reale Komponente in Betrieb genommen wird? Sinn machen, alle die gleichen Szenarien zu haben oder was ist ein gutes Entscheidungskriterium?

Es sieht so aus, als müssten Sie in diesen Szenarien eine Linie zeichnen. Halten Sie die lange Geschichte kurz - Unit-Tests und Mock-Objekte gehen natürlich zusammen. Komponententests erfordern ein reales Systemverhalten. Sie können verwendet werden, um die Verarbeitung von Daten zu überprüfen, die zwischen verschiedenen Einheiten oder Subsystemkomponenten ausgetauscht werden - z. B. der Komponenten- / Dienst-DB oder der Nachrichtenübermittlung, die keine Aufgabe auf Einheitenebene ist.

  

von der Controller-Schicht, was bedeutet, dass die REST-Dienste aufgerufen werden und die JSON-Ausgabe überprüft wird. Das ist genug?, Wir müssen nicht mehr Dinge in den anderen Schichten verifizieren? Ich weiß, die echte REST API zu nennen, die unter allen Schichten (Controller, Service, Dao) verwendet wird, aber das ist genug?

Nicht ganz richtig - beim Testen der Präsentationsschicht werden auch die darunter liegenden Ebenen trainiert ... also warum sollten Sie sich mit den restlichen Tests beschäftigen? Wenn Sie mit diesem Ansatz einverstanden sind, schlägt das Selenium-Team einen solchen DB-Validierung vor.

Wenn Sie über Bohnen und ViewHelpers hier

  

Wir haben eine Hilfsklasse, die ich für nicht sinnvoll halte, um Einheit und IT zu haben, so wie die meisten Methoden für nur einen Zweck. Ich denke, Unit Testing wird hier ausreichen, denkst du das auch ?.

Sie benötigen sowohl Einheit als auch IT, weil alle Gründe für andere Komponenten gelten. Nach Alleinverantwortung besteht kein Bedarf an IT-Tests.

  

machen das Testen der Einheit in einigen Fällen ist extrem schwierig, das ist eine gültige Begründung?

Gleiches gilt für alle gekapselten privaten (und statischen) Klassen, Methoden, Eigenschaften usw. Aber es gibt auch eine Möglichkeit, diese zu testen - wie Reflexion . Dies ist natürlich für einen speziellen Fall von Unit-Testing-Legacy-Code oder eine API, die Sie nicht ändern können. Wenn Sie es für Ihren eigenen Code brauchten, deutet dieser Mangel an Testbarkeit auf einen Designgeruch hin.

    
ekostadinov 07.10.2015, 05:55
quelle
2

Der Ansatz, den ich basierend auf den jüngsten Erfahrungen beim Testen von Java EE 7 und Spring-basierten Codebasen empfehlen würde, ist:

Verwenden Sie Integrationstests für einzelne Funktionen und vermeiden Sie Unit-Tests und Mocking. Jeder Integrationstest sollte Code von allen Layern abdecken, von der Darstellungsschicht bis zur Infrastrukturschicht (diese enthält wiederverwendbare Komponenten, die nicht anwendungs- oder domänenspezifisch sind, aber für die gewählte Architektur geeignet sind).

Die meisten Integrationstests sollten auf tatsächlichen Geschäftsanforderungen und Eingabedaten basieren. Andere können erstellt werden, um verbleibende Teile der Codebasis entsprechend dem Codeabdeckungsbericht auszuüben, der bei jeder Ausführung der Integrationstest-Suite erzeugt wird.

Wenn man also davon ausgeht, dass mit Integrationstests eine "vollständige" Codeabdeckung erreicht wird und sie ausreichend schnell laufen, gibt es nicht viel Grund für Unit-Tests. Ich habe die Erfahrung gemacht, dass Entwickler beim Schreiben von Komponententests zu viel Spott verwenden und oft brüchige Tests erstellen, die unnötige Implementierungsdetails überprüfen. Einheitentests können außerdem nicht das gleiche Maß an Vertrauen bieten wie Integrationstests, da sie normalerweise keine Datenbankabfragen, ORM-Mappings usw. abdecken.

    
Rogério 06.10.2015 18:55
quelle
2

Unit-Tests gelten genauso wie für Klassen und Komponenten. Sein Zweck ist:

  • Code schreiben (TDD).
  • Veranschaulichen Sie die Codeverwendung und machen Sie sie im Laufe der Zeit und mit Änderungen nachhaltig.
  • Bedecke so viele Grenzfälle wie möglich.

Wenn ein Problem mit einer bestimmten Verwendung oder bestimmten Parametern auftritt, reproduzieren Sie es zunächst mit einem neuen Test und beheben Sie es dann.

Verspotten sollte nur verwendet werden, wenn es erforderlich ist, ein eigenständiges Klassen- oder Komponentenverhalten zu testen, und die mokierte Funktion von außerhalb Ihrer Anwendung (z. B. einem E-Mail-Server) in Produktion geht. Es ist Overkill und nutzlos, wenn der Code bereits abgedeckt ist und das Mocking die Verantwortung für andere Arten von Tests wie Integrationstests überlagert.

Nun, da Sie wissen, dass jedes Stück Code funktioniert, wie arbeiten die Teile zusammen? Hier kommt der Integrationstest, bei dem es darum geht, wie die Komponenten unter verschiedenen Bedingungen und Umgebungen interagieren. Es gibt manchmal wenig Unterschiede zwischen UT und IT: zum Beispiel das Testen der Datenzugriffsschicht. Integrationstests werden für die gleichen Zwecke wie Komponententests verwendet, jedoch auf einer höheren, weniger atomaren Ebene, um die Anwendungsfälle für APIs, Services ... zu veranschaulichen.

Wie nennt man die "Integrationsschicht"?

Der Test der Darstellungsschicht ist eher Aufgabe des Funktionstests als Einheit oder Integration.

Sie haben auch nicht über Leistungstests gesprochen.

Schließlich ist das Ziel, den gesamten Code zusammen mit den Tests zu schreiben, Bugs, die nach der Reproduktion mit neuen Tests behoben wurden, und maximale Abdeckung, die alle Arten von Tests unter allen möglichen Bedingungen (Betriebssystem, Datenbanken, Browser ...) kumuliert. So validieren Sie Ihre allgemeine Testqualität mit:

  • ein Werkzeug, das die Abdeckung berechnet. Sie werden wahrscheinlich den Code instrumentieren müssen, um die Abdeckung von Funktionstests zu bewerten oder erweiterte JDK-Tools zu verwenden.
  • die Anzahl der Bugs, die durch das Fehlen von Tests bei einigen Komponenten, Diensten ... entstehen

Normalerweise halte ich eine Reihe von Tests für gut, wenn ich sie lese, gibt mir sofort keinen Zweifel darüber, wie man den Code, den sie abdecken, und das volle Vertrauen in seinen Vertrag, Fähigkeiten, Ein- und Ausgänge, Geschichte und Erschöpfbarkeit bei Anwendungsfällen, Stärke und Stabilität in Bezug auf Fehlermanagement und -bericht.

Nicht nur die Abdeckung ist eine wichtige Sache, sondern es könnte besser sein, ein paar weniger Tests zu haben, wenn Sie sich auf ihre Qualität konzentrieren: threadsafe, aus ungeordneten Methoden und Klassen, echte Bedingungen testen (keine "wenn Testbedingung" hackt) ).

Um Ihre Frage zu beantworten: Ich würde sagen, dass Sie angesichts der obigen Überlegungen keinen Integrationstest pro Schicht schreiben müssen, da Sie lieber eine andere Teststrategie wählen (Einheit, Integration, funktional, Leistung, Rauch, verspottet) ...) für jede Schicht.

    
Julien Carsique 06.10.2015 22:27
quelle