Java 当所有测试都是最新的时,如何运行Gradle测试?

Java 当所有测试都是最新的时,如何运行Gradle测试?,java,gradle,build.gradle,Java,Gradle,Build.gradle,我已经准备好了我的成绩脚本。 当我执行Gradle构建时,一切正常,它运行jUnit测试 之后,当我运行Gradle测试时,我得到以下结果: C:\Users\..\..\Project>gradle test :compileJava UP-TO-DATE :processResources UP-TO-DATE :classes UP-TO-DATE :compileTestJava UP-TO-DATE :processTestResources UP-TO-DATE :testCl

我已经准备好了我的成绩脚本。 当我执行Gradle构建时,一切正常,它运行jUnit测试

之后,当我运行Gradle测试时,我得到以下结果:

C:\Users\..\..\Project>gradle test
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
当我执行
gradle clean
时,gradle构建工作正常,当然。。。
我希望能够仅重置测试,而不是构建整个项目:我应该如何执行此操作?

一个选项是使用部分中的
--reruntasks
标志。这将重新运行测试任务及其所依赖的所有任务

如果您只对重新运行测试感兴趣,那么另一个选择是让gradle在执行测试之前清理测试结果。这可以使用
cleanTest
任务来完成

一些背景-Java插件为每个其他任务定义了一个干净的任务。根据文件:

cleanTaskName-删除由指定任务创建的文件。cleanJar将删除JAR任务创建的JAR文件,cleanTest将删除测试任务创建的测试结果

因此,重新运行测试所需的只是运行
cleanTest
任务,即:

gradle cleanTest测试

gradle测试--重新运行任务

指定忽略任何任务优化


来源:

其他选项是在build.gradle中添加以下内容:

test.outputs.upToDateWhen {false}
而且,
必须添加
——重新运行任务
确实是多余的。永远不会发生。创建一个
--no rerun tasks
并使
--rerun tasks
清理任务时成为默认值

以下是一个使用“build.gradle”文件的解决方案,以防您不想修改命令行:

test {
    dependsOn 'cleanTest'
    //Your previous task details (if any)
}
这是输出。请注意,与以前的输出相比,有2处更改:

1) 输出中将出现一个新的“cleanTest”任务

2) “测试”总是被清除的(即从不“更新”),因此每次都会执行:

$ gradle build
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:findMainClass
:jar
:bootRepackage
:assemble
:cleanTest
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test
:check
:build

这是格拉德尔最近博客上的话题。显示了使用
outputs.uptdatewhen{false}
的示例,并解释了其错误原因:

这实际上并不强制重新运行 这段代码的作者可能想说的是“总是重新运行我的测试”。但这段代码并不是这么做的。它只会将任务标记为过期,迫使Gradle重新创建输出。但问题是,如果启用了构建缓存,Gradle就不需要运行任务来重新创建输出。它将在缓存中找到一个条目,并将结果解压缩到测试的输出目录中

这段代码也是如此:

test.dependsOn cleanTest
Gradle将在清除输出后从构建缓存中解压缩测试结果,因此不会重新运行任何内容。简而言之,这些代码片段创建了一个非常昂贵的禁止操作程序

如果你现在在想“好吧,我也去停用缓存”,让我告诉你为什么不应该

然后,作者继续解释为什么重新运行某些测试是浪费时间:

绝大多数测试都应该是确定性的,即给定相同的输入,它们应该产生相同的结果

在少数情况下,如果您确实希望在代码未更改的情况下重新运行测试,则应将它们建模为输入。下面是博客文章中的两个示例,它们显示了如何添加输入,以便任务在其最新检查期间使用它

任务随机化测试(类型:测试){
systemProperty“random.testing.seed”,new random().nextInt()
}

任务系统集成测试(类型:测试){
inputs.property“integration.date”,LocalDate.now()
}
我建议您阅读整个博客文章。

--重新运行任务
是有效的,但由于它重新运行所有任务,因此效率低下

cleanTest
由于生成缓存的原因,其本身可能不够

因此,实现这一目标的最佳方法是:

./gradlew --no-build-cache cleanTest test
TL;博士


上述方法对我都不起作用。

对我来说,有效的方法是从
/Users//.gradle/caches/build-cache-1/

中的缓存目录中删除所有项目。根据给定的信息,这似乎是不必要的。如果应用程序代码和测试代码都没有更改,为什么需要重新运行测试?@Jolta我代码中的一些测试与三方输入相关,我运行测试不仅是为了确保我没有在代码中添加任何错误,而且是为了检查三方输入上是否有更改,我担心这会引起吹毛求疵,但我并不认为这是正确的思考方式:如果你有可变的三方投入,以某种方式模拟这些投入不是正确的处理方式吗?测试实际上应该是测试您正在编写的代码。如果你依赖于三方输入而不被接受,那么你是否有相当明显的获得误报的危险?该策略不应该迎合问题输入作为应用程序代码的一部分吗?@ MikOdToNoT考虑针对第三方在线服务测试代码。您可能希望监视服务API中可能的更改,以便能够尽快使用已部署的修复程序作出响应。CI测试不是一种很好的方法吗?使用mock只会告诉您自己的代码没有回归,但是依赖项仍然可能有变化。使用真正的服务将表明您的产品可以在当前环境中实际执行预期的操作。从集成测试的角度来看,这也是有效的,测试的目的是验证您的代码与其他代码位的集成,在不适合独立模拟的情况下,我将此技术用于我创建的运行功能测试的
funcTest
任务。这是一种比公认答案更好的方法,因为它只适用于所需的任务。
UpdateWhen
可以以任何“代码驱动”的方式使用,如系统属性、环境变量、项目
test.dependsOn cleanTest