it-swarm.com.de

Junit: Splitting-Integrationstest und Unit-Tests

Ich habe eine Menge Junit-Tests geerbt, aber diese Tests (außer den meisten, die nicht funktionieren) sind eine Mischung aus tatsächlichen Unit-Tests und Integrationstests (für die externe Systeme, Datenbanken usw. erforderlich sind).

Ich versuche also, einen Weg zu finden, wie ich sie tatsächlich trennen kann, damit ich den Komponententest Schön und schnell und die Integrationstests danach ausführen kann.

Die Optionen sind ..

  1. Teilen Sie sie in separate Verzeichnisse auf.

  2. Wechseln Sie zu Junit4 (ab Version 3) und versehen Sie die Klassen mit Anmerkungen, um sie zu trennen.

  3. Verwenden Sie eine Dateinamenskonvention, um festzustellen, was eine Klasse ist, d. H. AdapterATest und AdapterAIntergrationTest.

3 hat das Problem, dass Eclipse die Option "Alle Tests im ausgewählten Projekt/Paket oder Ordner ausführen" hat. Es würde also sehr schwierig werden, die Integrationstests durchzuführen.

2: Es besteht die Gefahr, dass Entwickler anfangen, Integrationstests in Komponententestklassen zu schreiben, und es wird einfach chaotisch.

1: Scheint die sauberste Lösung zu sein, aber mein Bauch sagt, dass es eine bessere Lösung geben muss.

Das ist also meine Frage, wie zerlegt man Integrationstests und richtige Komponententests?

122
jeff porter

Derzeit verwende ich aus organisatorischen Gründen (und aufgrund der Legacy von Junit 3) separate Verzeichnisse. Ich möchte jedoch selbst zu Anmerkungen übergehen, jetzt bin ich bei Junit 4.

Ich würde mir keine allzu großen Sorgen machen, wenn Entwickler Integrationstests in Ihre Komponententestklassen aufnehmen - fügen Sie bei Bedarf eine Regel in Ihre Codierungsstandards ein.

Ich bin interessiert zu wissen, welche anderen Lösungen es außer Anmerkungen oder physischer Trennung der Klassen geben könnte.

10

Sie können sie sehr einfach mit JUnit-Kategorien und Maven teilen.

Dies wird im Folgenden durch Splitting Unit- und Integrationstests sehr, sehr kurz dargestellt.

Eine Markierungsschnittstelle definieren

Diese Schnittstelle wird verwendet, um alle Tests zu markieren, die als Integrationstests ausgeführt werden sollen.

public interface IntegrationTest {}

Markieren Sie Ihre Testklassen

Fügen Sie die Kategorieanmerkung oben in Ihre Testklasse ein. Es nimmt den Namen Ihrer neuen Schnittstelle an.

import org.junit.experimental.categories.Category;
@Category(IntegrationTest.class)
public class ExampleIntegrationTest{
  @Test
  public void longRunningServiceTest() throws Exception {
  }
}

Maven Unit Tests konfigurieren

Wir fügen dem Maven-todsicheren Plugin einfach eine Konfiguration hinzu, damit Integrationstests ignoriert werden.

<plugin>
  <groupId>org.Apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.11</version>
  <dependencies>
   <dependency>
     <groupId>org.Apache.maven.surefire</groupId>
     <artifactId>surefire-junit47</artifactId>
     <version>2.12</version>
   </dependency>
  </dependencies>
  <configuration>
    <includes>
      <include>**/*.class</include>
    </includes>
    <excludedGroups>com.test.annotation.type.IntegrationTest</excludedGroups>
  </configuration>
</plugin>

Wenn Sie einen mvn-Reinigungstest durchführen, werden nur Ihre nicht markierten Komponententests ausgeführt.

Maven-Integrationstests konfigurieren

Gehen Sie folgendermaßen vor, um nur die Integrationstests auszuführen:

<plugin>
  <groupId>org.Apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.11</version>
  <dependencies>
   <dependency>
     <groupId>org.Apache.maven.surefire</groupId>
     <artifactId>surefire-junit47</artifactId>
     <version>2.12</version>
   </dependency>
  </dependencies>
  <configuration>
    <groups>com.test.annotation.type.IntegrationTest</groups>
  </configuration>
</plugin>

Wenn Sie dies in ein Profil mit der ID IT einbinden, können Sie nur die Schnelltests mit mvn clean install Ausführen. Verwenden Sie mvn clean install -P IT, Um nur die Integrationstests/langsamen Tests auszuführen.

In den meisten Fällen möchten Sie jedoch die Schnelltests standardmäßig ausführen und all mit -P IT Testen. Wenn dies der Fall ist, müssen Sie einen Trick anwenden:

<profiles>
    <profile>
        <id>IT</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.Apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <excludedGroups>Java.io.Serializable</excludedGroups> <!-- An empty element doesn't overwrite, so I'm using an interface here which no one will ever use -->
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

Wie Sie sehen, schließe ich Tests aus, die mit Java.io.Serializable Gekennzeichnet sind. Dies ist notwendig, da das Profil die Standardkonfiguration des Surefire-Plugins erbt. Selbst wenn Sie <excludedGroups/> Oder <excludedGroups></excludedGroups> Sagen, wird der Wert com.test.annotation.type.IntegrationTest Verwendet.

Sie können none auch nicht verwenden, da es sich um eine Schnittstelle im Klassenpfad handeln muss (Maven prüft dies).

Anmerkungen:

  • Die Abhängigkeit von surefire-junit47 Ist nur erforderlich, wenn Maven nicht automatisch zum JUnit 4-Runner wechselt. Die Verwendung des Elements groups oder excludedGroups sollte den Schalter auslösen. siehe hier .
  • Der größte Teil des obigen Codes stammt aus der Dokumentation des Maven Failsafe-Plugins. Siehe Abschnitt "Verwenden von JUnit-Kategorien" auf dieser Seite .
  • Während meiner Tests stellte ich fest, dass dies sogar funktioniert, wenn Sie @RunWith() Annotationen verwenden, um Suites oder Spring-basierte Tests auszuführen.
139
John Dobie

Wir verwenden das Maven Surefire Plugin, um Komponententests durchzuführen, und das Maven Failsafe Plugin, um Integrationstests durchzuführen. Unit-Tests folgen dem **/Test*.Java **/*Test.Java **/*TestCase.Java Namenskonventionen, Integrationstests - **/IT*.Java **/*IT.Java **/*ITCase.Java. Also ist es tatsächlich Ihre Option Nummer drei.

In einigen Projekten verwenden wir TestNG und definieren verschiedene Testgruppen für Integrations-/Unit-Tests. Dies ist jedoch wahrscheinlich nicht für Sie geeignet.

38
lexicore

Ich würde auf Junit4 umsteigen, nur weil ich es habe :)

Sie können sie in verschiedene Testsuiten unterteilen. Ich weiß nicht, wie sie in Junit3 organisiert sind, aber es sollte in Junit4 einfach sein, Testsuiten aufzubauen und alle realen Komponententests in eine von ihnen zu integrieren und dann eine zweite Suite für die Integrationstests zu verwenden.

Definieren Sie nun eine Ausführungskonfiguration für beide Suites in Eclipse, und Sie können problemlos eine einzelne Suite ausführen. Diese Suiten können auch über einen automatisierten Prozess gestartet werden, sodass Sie die Komponententests jedes Mal ausführen können, wenn sich die Quelle ändert, und möglicherweise die Integrationstests (wenn sie wirklich umfangreich sind) nur einmal am Tag oder einmal pro Stunde.

12
Janusz

Die Verwendung von IfProfileValue Spring Annotation ermöglicht es, dies zu erreichen , ohne dass ein Maven-Plugin oder eine Konfiguration erforderlich ist.

Kommentieren Sie die Integrationstestklassen oder -methoden mit dem IfProfileValue

import org.springframework.test.annotation.IfProfileValue;

@IfProfileValue(name="test-groups", value="integration")
public class ExampleIntegrationTest{
    @Test
    public void longRunningServiceTest() throws Exception {
    }
} 

Nur mit Unit-Tests ausführen:

mvn clean test

So führen Sie einen Integrationstest und Unit-Tests aus:

mvn clean test -Dtest-groups=integration

Außerdem würde "Run all test" in einem IDE nur Komponententest ausführen. Add -Dtest-groups=integration to VM Argumente zum Ausführen von Integrations- und Komponententests.

8
Mit Mehta

Es gibt keine richtige Antwort. Wie Sie bereits erklärt haben, gibt es verschiedene Möglichkeiten, dies zu tun. Ich habe sowohl das Dateinamensschema als auch die Aufteilung in verschiedene Verzeichnisse durchgeführt.

Es hört sich so an, als ob das Aufteilen von Dingen in verschiedene Verzeichnisse für Sie besser funktionieren könnte, und das scheint mir ein bisschen klarer zu sein, also würde ich mich dazu neigen.

Ich glaube nicht, dass ich es mit Anmerkungen versuchen würde, weil mir das feiner erscheint. Wollen Sie wirklich, dass diese beiden Testtypen in derselben Datei gemischt werden? Würde ich nicht.

6
ndp