在之前的一个项目中,我使用Spock测试框架对Java代码进行单元测试。我发现这真的很有成效,所以我试图将Spock测试添加到我当前的项目中,该项目使用Maven作为其构建工具(之前的项目使用Gradle)。虽然我可以让Maven编译我的Spock测试(使用groovy-eclipse-compiler
),但我无法让Maven运行测试。
我做了一个简单的例子来演示我的问题与2个文件:
-
pom.xml
-
src/test/java/ASpec.groovy
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>
ASpec.groovy
目录:
import spock.lang.Specification
class ASpec extends Specification {
def "Test A"(){
// Always fail
expect: false
}
}
当我执行mvn clean test
(或mvn clean install
)时,我希望我的单个单元测试运行并失败。当它被编译时,Maven不会运行它。有谁知道如何从Maven运行Spock单元测试(或者如果可能的话?)
(为了保持示例简单,我没有将测试放在包中。此外,我还将groovy代码放在src/test/java中,以避免将示例配置为从其他目录中获取源文件,这也是为了使示例尽可能简单。
这个答案纯粹是对@PeterNiederwieser的回答的补充。在其中,他提到您可以配置Surefire使用的名称模式。下面是一个对我有用的例子:
<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>
来源正如我在评论中提到的,我不确定为什么**/*Spec.groovy
不起作用,但我很高兴能够在这里使用正常的Spock约定。
Maven Surefire根据名称查找测试类。要么将类名更改为ATest
,要么重新配置Surefire使用的名称模式。spock-example项目的POM演示了如何执行后者。
我也需要将Spock添加到我现有的java web应用程序中。我试过彼得斯,但对我不起作用。gmavenplus-plugin不知怎么的(不知道)用一个非常旧的google lib取代了我的guava依赖,我的Spring应用程序因为一个不存在的方法而崩溃了。
经过两三次尝试,我终于能够集成我的Spock单元测试和集成测试,更重要的是将Spock groovy类的编译从我现有的Java/Junit Spring/Hibernate应用程序中分离出来。
当然,如果我有gradle,问题就解决了…但这是一个遗留项目,因此我没有选择。
下面是我添加的插件。请注意Spock单元测试以Spec结束。Spock集成测试以IT结束(但很可能应该是SpecIT)。我把我的Spock测试放在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>
下面是我的依赖项:
<!--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>
为了让你知道,我最初的POM完全没有显式插件。所以我的项目有一个非常简单的POM。因此,它应该为您工作。这是一个Java 1.7项目。
…最后,只是给你一些信心,这不是一个垃圾帖子,我做了多次测试,以确保上述工作:
只构建没有测试的WAR,并在本地部署和冒烟测试
mvn clean install -DskipTests -Dmaven.test.skip=true做一个测试编译,看看Groovy单元测试是否也被编译了
mvn - x清洁任意在没有集成测试的情况下进行一次全新安装(我确保它在此测试中失败),并查看Groovy单元测试是否运行
mvn全新安装-DskipITs直接运行集成测试
mvn破损安全:集成测试
我本想附上上面的截图作为证据,但它必须被审查……所以,我真诚地希望这能帮助你,因为我要发疯了,试图让这个工作…Maven是一个巨大的学科领域。祝你好运!
我遇到的一个问题是不兼容的依赖项。
spock-core
依赖当然会拉入它需要的groovy版本的依赖。但是其他依赖项或插件(我认为在我的情况下是gmaven-plus
插件)可能会拉入不同的,不兼容的groovy版本。
我通过显式地给出我想要使用的groovy包的依赖项来修复这个问题。