Maven Project Setup for Mixing Spock 1.x and JUnit 5 Tests

I create a sample Groovy project for Maven, that mixes Spock tests and JUnit 5 tests in one project. In the next section I'll describe how to set up such kind of Maven project.

Enable Groovy in the Project

First at all, you have to enable Groovy in your project. One possibility is to add the GMavenPlus Plugin to your project.

 1<build>
 2    <plugins>
 3        <plugin>
 4            <groupId>org.codehaus.gmavenplus</groupId>
 5            <artifactId>gmavenplus-plugin</artifactId>
 6            <version>1.6.2</version>
 7            <executions>
 8                <execution>
 9                    <goals>
10                        <goal>addSources</goal>
11                        <goal>addTestSources</goal>
12                        <goal>compile</goal>
13                        <goal>compileTests</goal>
14                    </goals>
15                </execution>
16            </executions>
17        </plugin>
18    </plugins>
19</build>

The goals addSources and addTestSources add Groovy (test) sources to Maven's main (test) sources. The default locations are src/main/groovy (for main source) and src/test/groovy (for test source). Goals compile and compileTests compile the Groovy (test) code. If you don't have Groovy main code, you can omit addSource and compile.

This above configuration is always using the latest released Groovy version. If you want to ensure that a specific Groovy version is used, you have to add the specific Groovy dependency to your classpath.

1   <dependencies>
2        <dependency>
3            <groupId>org.codehaus.groovy</groupId>
4            <artifactId>groovy</artifactId>
5            <version>2.5.6</version>
6        </dependency>
7  </dependencies>

Enable JUnit 5 in the Project

The simplest setup for using JUnit 5 in your project is to add the JUnit Jupiter dependency in your test class path and to configure the correct version of Maven Surefire Plugin (at least version 2.22.0).

 1    <dependencies>
 2<!--... maybe more dependencies -->
 3        <dependency>
 4            <groupId>org.junit.jupiter</groupId>
 5            <artifactId>junit-jupiter</artifactId>
 6            <scope>test</scope>
 7        </dependency>
 8    </dependencies>
 9
10    <dependencyManagement>
11        <dependencies>
12            <dependency>
13                <groupId>org.junit</groupId>
14                <artifactId>junit-bom</artifactId>
15                <version>${junit.jupiter.version}</version>
16                <scope>import</scope>
17                <type>pom</type>
18            </dependency>
19        </dependencies>
20    </dependencyManagement>
21    <build>
22        <plugins>
23        <!-- other plugins -->
24            <plugin>
25                <artifactId>maven-surefire-plugin</artifactId>
26                <version>2.22.1</version>
27            </plugin>
28        </plugins>
29    </build>

Enable Spock in the Project

Choosing the right Spock dependency depends on which Groovy version you are using in the project. In our case, a Groovy version 2.5. So we need Spock in version 1.x-groovy-2.5 in our test class path.

1    <dependencies>
2        <!-- more dependencies -->
3        <dependency>
4            <groupId>org.spockframework</groupId>
5            <artifactId>spock-core</artifactId>
6            <version>1.3-groovy-2.5</version>
7            <scope>test</scope>
8        </dependency>
9    </dependencies>

Now the expectation is that the Spock tests and the JUnit5 tests are executed in the Maven build. But only the JUnit5 tests are executed by Maven. So what happened?

I started to change the Maven Surefire Plugin version to 2.21.0. Then the Spock tests were executed, but no JUnit5 tests. The reason is that in the version 2.22.0 of Maven Surefire Plugin JUnit4 provider is replaced by JUnit Platform Provider as default. But Spock in version 1.x is based on JUnit4. This will be changed in Spock version 2. This version will be based on the JUnit5 Platform. Thus, for Spock 1.x, we have to add JUnit Vintage dependency to our test class path.

1    <dependencies>
2        <!-- more dependencies -->
3          <dependency>  <!--Only necessary for surefire to run spock tests during the maven build -->
4            <groupId>org.junit.vintage</groupId>
5            <artifactId>junit-vintage-engine</artifactId>
6            <scope>test</scope>
7        </dependency>
8    </dependencies>

This allows running elder JUnit (3/4) tests on the JUnit Platform. With this configuration both, Spock and JUnit 5 tests, are executed in the Maven build.