如何在Gradle项目中运行JUnit5和Spock 2.0测试

如何在Gradle项目中运行JUnit5和Spock 2.0测试,gradle,spock,junit5,Gradle,Spock,Junit5,我有一个简单的项目,我希望能够运行JUnit5单元测试和Spock2功能测试。如果我在下面的build.gradle中注释掉了Spock依赖项,那么我的JUnit5测试将运行并通过。但是,如果我在准备添加Spock测试时取消对Spock依赖项的注释,JUnit5测试将开始失败 我的身材。格雷德尔: buildscript { repositories { maven { url "https://plugins.gradle.org/m2/" }

我有一个简单的项目,我希望能够运行JUnit5单元测试和Spock2功能测试。如果我在下面的build.gradle中注释掉了Spock依赖项,那么我的JUnit5测试将运行并通过。但是,如果我在准备添加Spock测试时取消对Spock依赖项的注释,JUnit5测试将开始失败

我的身材。格雷德尔:

buildscript {
    repositories {
        maven { url "https://plugins.gradle.org/m2/" }
    }
    dependencies {
        classpath(
          "org.springframework.boot:spring-boot-gradle-plugin:2.1.6.RELEASE",
          'net.researchgate:gradle-release:2.8.0'
          )
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'net.researchgate.release'
apply plugin: 'groovy'

repositories {
    mavenCentral()
    jcenter()
}

sourceCompatibility = 11
targetCompatibility = 11

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
    testImplementation 'org.codehaus.groovy:groovy:3.0.5'
    testImplementation group: 'org.spockframework', name: 'spock-spring', version: '2.0-M3-groovy-3.0'
    testImplementation group: 'org.spockframework', name: 'spock-core', version: '2.0-M3-groovy-3.0'
    //testImplementation group: 'org.spockframework', name: 'spock-junit4', version: '2.0-M3-groovy-3.0'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
}

test {
    useJUnitPlatform()
}

jar {
   enabled = true
}

bootJar {
    archiveFileName = "app.jar"
}
如果取消对Spock依赖项的注释,则会出现错误:

org.gradle.api.internal.tasks.testing.TestSuiteExecutionException: Could not complete execution for Gradle Test Executor 3.
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:63)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at com.sun.proxy.$Proxy2.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:132)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
    at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:412)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.util.ServiceConfigurationError: org.junit.platform.engine.TestEngine: org.spockframework.runtime.SpockEngine Unable to get public no-arg constructor
    at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:581)
    at java.base/java.util.ServiceLoader.getConstructor(ServiceLoader.java:672)
    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1232)
    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1264)
    at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1299)
    at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1384)
    at java.base/java.lang.Iterable.forEach(Iterable.java:74)
    at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:87)
    at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:67)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:97)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
    ... 25 more
Caused by: java.lang.NoClassDefFoundError: org/junit/platform/engine/support/discovery/SelectorResolver
    at java.base/java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.base/java.lang.Class.privateGetDeclaredConstructors(Class.java:3137)
    at java.base/java.lang.Class.getConstructor0(Class.java:3342)
    at java.base/java.lang.Class.getConstructor(Class.java:2151)
    at java.base/java.util.ServiceLoader$1.run(ServiceLoader.java:659)
    at java.base/java.util.ServiceLoader$1.run(ServiceLoader.java:656)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.util.ServiceLoader.getConstructor(ServiceLoader.java:667)
    ... 36 more
Caused by: java.lang.ClassNotFoundException: org.junit.platform.engine.support.discovery.SelectorResolver
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 44 more

我在这里创建了一个基本应用程序:

组“com.example”
版本“1.0”
应用插件:“groovy”
应用插件:“java”
sourceCompatibility=1.8
测试{useJUnitPlatform()}
存储库{
mavenCentral()
}
依赖关系{
实现'org.codehaus.groovy:groovy-all:3.0.6'
实现“org.springframework:spring上下文:5.3.1”
测试实现'org.junit.jupiter:junitjupiter:5.7.0'
测试实现'org.junit.jupiter:junitjupiter api:5.7.0'
测试实现“org.spockframework:spock核心:2.0-M4-groovy-3.0”
}
源集{
主要{
棒极了{
srcDirs=['src/main/java','src/main/groovy']
}
资源{
srcDirs=['src/main/resources']
}
}
}
当我把所有东西都升级到最新版本时,我得到了一个错误,警告我版本不兼容。访问的结果页面包含以下表格,但格式不正确。因此,我将其格式化为更具可读性,并将其包括在下面:

| Spock version | Groovy version | JUnit version | Grails version | Spring version |
|:--------------|:---------------|:--------------|:---------------|:---------------|
| 0.5-groovy-1.6 | 1.6.1-1.6.x | 4.7-4.x | 1.2.0-1.2.x | 2.5.0-3.x |
| 0.5-groovy-1.7 | 1.7.0-1.7.x | 4.7-4.x | 1.3.0-1.3.x | 2.5.0-3.x |
| 0.6-groovy-1.7 | 1.7.0-1.7.x | 4.7-4.x | 1.3.0-1.3.x | 2.5.0-3.x |
| 0.6-groovy-1.8 | 1.8.1-1.8.x | 4.7-4.x | 2.0-2.x | 2.5.0-3.x |
| 0.7-groovy-1.8 | 1.8.1-1.8.x | 4.7-4.x | 2.0-2.x | 2.5.0-3.x |
| 0.7-groovy-2.0 | 2.0.0 -2.x.x | 4.7-4.x | 2.2-2.x | 2.5.0-3.x |
| 1.0-groovy-2.0 | 2.0.0 -2.2.x | 4.7-4.x | 2.2-2.x | 2.5.0-4.x |
| 1.0-groovy-2.3 | 2.3.0 -2.3.x | 4.7-4.x | 2.2-2.x | 2.5.0-4.x |
| 1.0-groovy-2.4 | 2.4.0 -2.x.x | 4.7-4.x | 2.2-2.x | 2.5.0-4.x |

| Spock version | Groovy version | JUnit version | Grails version | Spring version |
|:--------------|:---------------|:--------------|:---------------|:---------------|
| 1.1-groovy-2.0-SNAPSHOT | 2.0.0 -2.2.x | 4.7-4.x | 2.2-2.x | 2.5.0-4.x |
| 1.1-groovy-2.3-SNAPSHOT | 2.3.0 -2.3.x | 4.7-4.x | 2.2-2.x | 2.5.0-4.x |
| 1.1-groovy-2.4-SNAPSHOT | 2.4.0 -2.x.x | 4.7-4.x | 2.2-2.x | 2.5.0-4.x |

我最终使用了新旧JUnit引擎:

test.useJUnitPlatform() {
        includeEngines 'junit-vintage'
        includeEngines 'junit-jupiter'
    }
,其中,
vintage
代表斯波克,
jupiter
代表JUnit5


它可能不是最好的解决方案,但很有效:)

试试JUnit
5.7.0
或更高版本。它使用的是spock的一个相当旧的版本,请看一看。而且它根本不使用JUnit 5。我以为您能够管理版本的颠簸,但是我已经为您更新了答案,包括这一点,并将更新推到我的repo上。Groovy/Spock/Junit之间都有一些版本依赖关系,因此即使我提供了可以工作的版本,它们也可能与您的版本不兼容。您的测试实际运行了吗?我在这里的示例中没有看到
test{useJUnitPlatform()}
,这在Spock 2.xYou确实是正确的-我已将其添加到脚本中,它现在从gradle成功运行测试