webentwicklung-frage-antwort-db.com.de

Spock-Unit-Tests mit Maven durchführen

Bei einem früheren Projekt habe ich das Spock-Testframework verwendet, um meinen Java-Code zu testen. Ich fand das wirklich produktiv, deshalb versuche ich, Spock-Tests zu meinem aktuellen Projekt hinzuzufügen, das Maven als Build-Tool verwendet (das vorherige Projekt verwendete Gradle). Während ich Maven dazu bringen kann, meine Spock-Tests zu kompilieren (mithilfe von groovy-Eclipse-compiler), kann ich Maven nicht dazu bringen, die Tests auszuführen. 

Ich habe ein einfaches Beispiel gemacht, um mein Problem mit 2 Dateien zu veranschaulichen:

  • pom.xml
  • src/test/Java/ASpec.groovy

Inhalte von pom.xml:

<project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>my.group</groupId>
    <artifactId>my-artifact</artifactId>
    <version>0.1-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>
            <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.0.8</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-core</artifactId>
            <version>0.7-groovy-2.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <compilerId>groovy-Eclipse-compiler</compilerId>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.codehaus.groovy</groupId>
                        <artifactId>groovy-Eclipse-compiler</artifactId>
                        <version>2.8.0-01</version>
                    </dependency>
                    <dependency>
                        <groupId>org.codehaus.groovy</groupId>
                        <artifactId>groovy-Eclipse-batch</artifactId>
                        <version>2.1.8-01</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

Inhalte von ASpec.groovy:

import spock.lang.Specification

class ASpec extends Specification {

    def "Test A"(){
        // Always fail
        expect: false
    }
}

Wenn ich mvn clean test (oder mvn clean install) ausführen, würde ich erwarten, dass mein Einzelgerätetest ausgeführt wird und fehlschlägt. Während es kompiliert wird, führt Maven es nicht aus. Weiß jemand, wie man einen Spock-Unit-Test von Maven durchführt (oder ob es möglich ist?)

(Ich habe meinen Test nicht in ein Paket aufgenommen, um das Beispiel einfach zu halten. Außerdem habe ich meinen groovigen Code in src/test/Java eingefügt, um zu vermeiden, dass das Beispiel so konfiguriert wird, dass Quelldateien aus einem zusätzlichen Verzeichnis abgerufen werden, um das Beispiel erneut zu behalten so einfach wie möglich.)

19
Neil Stevens

Maven Surefire findet Testklassen anhand ihres Namens. Ändern Sie entweder den Klassennamen in ATest oder konfigurieren Sie das von Surefire verwendete Namensmuster neu. Das POM für das spock-example - Projekt zeigt, wie das letztere ausgeführt wird.

20

Diese Antwort ergänzt die Antwort von @ PeterNiederwieser. Darin erwähnt er, dass Sie das von Surefire verwendete Namensmuster konfigurieren können. Hier ist ein Beispiel, was für mich funktioniert hat:

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.18</version>
    <configuration>
        <includes>
            <!-- By default only files ending in 'Test' will be included, so also include support for Spock style naming convention -->
            <!-- Oddly enough for Groovy files, *Spec.groovy does not work, but *Spec.Java does -->
            <include>**/*Test.Java</include>
            <include>**/*Spec.Java</include>
        </includes>
    </configuration>
</plugin>

Quelle

Wie ich in den Kommentaren erwähne, bin ich nicht sicher, warum **/*Spec.groovy nicht funktioniert hat, aber ich bin froh, dass ich hier die normale Spock-Konvention anwenden kann.

21
mnd

Ich hatte die gleiche Anforderung, Spock zu meiner vorhandenen Java-Web-App hinzuzufügen. Ich habe es mit Peters versucht, aber es funktionierte nicht für mich. gmavenplus-plugin hat irgendwie (keine Ahnung) meine Guavenabhängigkeit durch eine sehr alte Google-Lib ersetzt, und meine Spring-Anwendung hat sich wegen einer nicht existierenden Methode beschwert.

Nach buchstäblich etwa zwei oder drei Dutzend Versuchen konnte ich meine Spock Unit-Tests und Integrationstests integrieren und vor allem die Zusammenstellung der Spock-Groovy-Klassen von meiner vorhandenen Java/Junit Spring/Hibernate-Anwendung isolieren.

Wenn ich gradle hätte, wäre das Problem natürlich gelöst worden ... aber dies ist ein Vermächtnisprojekt und daher hatte ich keine Wahl.

Nachfolgend sind die Plugins aufgeführt, die ich hinzugefügt habe .. Bitte beachten Sie, dass die Spock-Unit-Tests mit Spec .. enden. Die Spock-Integrationstests enden mit IT (sollte aber höchstwahrscheinlich SpecIT sein). Ich lege meine Spock-Tests unter src/Test/groovig.

         <plugins>
            <plugin>
                <groupId>org.codehaus.gmavenplus</groupId>
                <artifactId>gmavenplus-plugin</artifactId>
                <version>1.4</version>
                <executions>
                    <execution>
                        <!-- Without joint compilation - no dependencies between Java and Groovy (inheritance)-->
                        <goals>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <sources>
                        <source>
                            <directory>${project.basedir}/src/main/Java/groovy</directory>
                            <includes>
                                <include>**/*.groovy</include>
                            </includes>
                        </source>
                    </sources>
                    <testSources>
                        <testSource>
                            <directory>${project.basedir}/src/test/groovy</directory>
                            <includes>
                                <include>**/*.groovy</include>
                            </includes>
                        </testSource>
                    </testSources>

                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.18.1</version>
                <configuration>
                    <testSourceDirectory>src/test/groovy</testSourceDirectory>
                    <testSourceDirectory>src/test/Java</testSourceDirectory>
                    <includes>
                        <include>**/*Spec.Java</include>
                        <!-- Yes, .Java extension -->
                        <include>**/*Test.Java</include>
                        <!-- Just in case having "normal" JUnit tests -->
                    </includes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.20</version>
                <configuration>
                    <useFile>false</useFile>
                    <includes>
                        <include>**/*IT.Java</include>
                    </includes>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>

Und hier sind meine Abhängigkeiten:

        <!--Spock -->
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy</artifactId>
            <version>2.4.7</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-core</artifactId>
            <version>1.1-groovy-2.4</version>
        </dependency>

        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-spring</artifactId>
            <version>1.1-groovy-2.4</version>
        </dependency>

        <dependency>
            <groupId>org.codehaus.groovy.modules.http-builder</groupId>
            <artifactId>http-builder</artifactId>
            <version>0.7.1</version>
        </dependency>
        <!--Spock mocking dependencies -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib-nodep</artifactId>
            <version>3.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.objenesis</groupId>
            <artifactId>objenesis</artifactId>
            <version>2.6</version>
        </dependency>

Und um Sie wissen zu lassen, hatte mein ursprüngliches POM absolut keine expliziten Plugins AT ALL. Ich hatte also ein sehr einfaches POM für mein Projekt. Es sollte also sollte für Sie arbeiten. _. Es ist ein Java 1.7-Projekt.

... und um Ihnen ein gewisses Vertrauen zu geben, dass dies keine Mülldeponie ist, habe ich mehrere Tests durchgeführt, um sicherzustellen, dass das oben genannte funktioniert:

  1. Erstellen Sie einfach die WAR ohne die Tests und stellen Sie sie lokal bereit
    mvn clean install -DskipTests -Dmaven.test.skip = true

  2. Machen Sie eine Testkompilierung und sehen Sie, ob die Groovy Unit-Tests ebenfalls kompiliert werden
    mvn -X reines Testkompilieren

  3. Führen Sie eine Neuinstallation ohne den Integrationstest durch (ich habe sichergestellt, dass der Test für diesen Test fehlgeschlagen ist), und prüfen Sie, ob die Groovy-Unit-Tests ausgeführt werden
    mvn clean install -DskipITs

  4. Führen Sie einfach den Integrationstest aus
    mvn ausfallsicher: Integrationstest

Ich hätte gerne Screenshots von den oben genannten als Beweis aufgenommen, aber es hätte zensiert werden müssen ... Ich hoffe aufrichtig, dass dies Ihnen hilft, da ich mich bemühte, diese Arbeit zum Laufen zu bringen ... Maven ist ein riesiges Thema Bereich. Viel Glück: =) 

1
Beezer