On a previous project I used the Spock testing framework to unit test my Java code. I found this really productive so I am trying to add Spock tests to my current project which uses Maven as its build tool (The previous project used Gradle). While I can get Maven to compile my Spock tests (using groovy-eclipse-compiler
), I am unable to get Maven to run the tests.
I've made a simple example to demonstrate my problem with 2 files:
pom.xml
src/test/java/ASpec.groovy
Contents of 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>
Contents of ASpec.groovy
:
import spock.lang.Specification
class ASpec extends Specification {
def "Test A"(){
// Always fail
expect: false
}
}
When I execute mvn clean test
(or mvn clean install
) I would expect my single unit test to be run and fail. While it is compiled, Maven does not run it. Does any one know how to run a Spock unit test from Maven (or if it is possible?)
(I have not put my test in a package to keep the example simple. Also I have put my groovy code in src/test/java to avoid configuring the example to pick up source files from an additional directory, again to keep the example as simple as possible.)
Maven Surefire finds test classes by their name. Either change the class name to ATest
, or reconfigure the name pattern used by Surefire. The POM for the spock-example project demonstrates how to do the latter.
This answer is purely supplemental to @PeterNiederwieser's answer. In it he mentions that you can configure the name pattern used by Surefire. Here is an example of what worked for me:
<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>
As I mention in the comments, I'm not sure why **/*Spec.groovy
didn't work, but I'm happy to be able to use the normal Spock convention here.
I had the same requirement to add Spock to my existing java web app. I tried Peters but it did not work for me. gmavenplus-plugin somehow (no idea) replaced my guava dependency with a very old google lib and my Spring application broke complaining about a non-existent method.
After literally maybe 2 or 3 dozen attempts, I finally was able to integrate my Spock Unit tests, and Integration tests and more importantly to isolate the compilation of the Spock groovy classes from my existing Java/Junit Spring/Hibernate application.
Of course if I had gradle it would have solved the issue...but this is a legacy project and therefore I had not the choice.
Below are the plugins I added. Please note the Spock unit tests end with Spec. The Spock integration tests end with IT (but most probably should be SpecIT). I put my Spock tests under src/test/groovy.
<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>
And here are my dependencies:
<!--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>
And just to let you know, my original POM had absolutely no explicit plugins AT ALL. So I had a very simply POM for my project. So, it should work for you. It is a Java 1.7 project.
...and finally, just to give you some confidence that this is not a rubbish post, I did multiple tests in order to ensure the above worked:
Just build the WAR without the tests and deploy and smoke test it locally
mvn clean install -DskipTests -Dmaven.test.skip=trueDo a test compile and see if the Groovy Unit tests get compiled as well
mvn -X clean test-compileDo a clean install without the Integration test (i made sure it was failing for this test) and see if the Groovy unit tests are run
mvn clean install -DskipITsJust run the integration test
mvn failsafe:integration-test
I would have liked to include screenshots of the above as proof but it would have had to be censored...So, I sincerely hope this helps you, as I was going mental trying to get this working...Maven is a huge subject area. Good luck :=)
来源:https://stackoverflow.com/questions/25186004/running-spock-unit-tests-with-maven