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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29427020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:58:23  来源:igfitidea点击:

How to run Gradle test when all tests are UP-TO-DATE?

javagradlebuild.gradle

提问by USer22999299

I have my grade script set up. When I execute the Gradle build, everything is working and it runs the jUnit tests.

我已经设置了我的成绩脚本。当我执行 Gradle 构建时,一切正常并运行 jUnit 测试。

After that when I run the Gradle test I get the following:

之后,当我运行 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

When I perform gradle clean, then Gradle build works, of course... I want to be able to reset only the tests, not build the whole project: how should I do this?

当我执行gradle clean,然后 Gradle 构建工作,当然......我希望能够只重置测试,而不是构建整个项目:我应该怎么做?

采纳答案by Amnon Shochot

One option would be using the --rerun-tasksflag in the command line. This would rerun all the the test task and all the tasks it depends on.

一种选择是--rerun-tasks命令行中使用该标志。这将重新运行所有测试任务及其依赖的所有任务。

If you're only interested in rerunning the tests then another option would be to make gradle clean the tests results before executing the tests. This can be done using the cleanTesttask.

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

Some background - the Java plugin defines a clean tasks to each of the other tasks. According to the documentation:

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

cleanTaskName- Deletes files created by specified task. cleanJar will delete the JAR file created by the jar task, and cleanTest will delete the test results created by the test task.

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

Therefore, all you need in order to re-run your tests is to also run the cleanTesttask, i.e.:
gradle cleanTest test

因此,为了重新运行测试,您所需要的只是运行cleanTest任务,即:
gradle cleanTest test

回答by Martin Andersson

gradle test --rerun-tasks

gradle test --rerun-tasks

Specifies that any task optimization is ignored.

指定忽略任何任务优化。

Source: https://gradle.org/docs/current/userguide/gradle_command_line.html

来源:https: //gradle.org/docs/current/userguide/gradle_command_line.html

回答by Franti?ek Hartman

Other option would be to add following in your build.gradle:

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

test.outputs.upToDateWhen {false}

回答by user1648995

Also, having to add --rerun-tasksis really redundant. Never happens. Create a --no-rerun-tasksand make --rerun-tasksdefault when cleanTask

此外,不得不添加--rerun-tasks真的是多余的。永远不会发生。创建一个--no-rerun-tasks并设为--rerun-tasks默认cleanTask

回答by TealSeed

Here's a solution using the "build.gradle" file, in case you don't want to modify your command line:

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

test {
    dependsOn 'cleanTest'
    //Your previous task details (if any)
}

And here's the output. Notice 2 changes from your previous output:

这是输出。请注意与之前的输出相比有 2 处更改:

1) A new 'cleanTest' task appears in the output.

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

2) 'test' is always cleaned (i.e. never 'UP-TO-DATE') so it gets executed every time:

2) 'test' 总是被清理(即从不 'UP-TO-DATE'),所以它每次都会被执行:

$ 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

回答by mike rodent

I think this is a valid question given that it is possible in Gradle to run this command test, and what happens is that nothing happens!

我认为这是一个有效的问题,因为可以在 Gradle 中运行此命令test,但什么也没有发生!

But I would question the need ever to do this, as Jolta said in his comment: if no code has changed why do you need to re-test? If you have doubts about third-party input I'd say you need to cater for this in your app code. If you have worries that your code might be "flaky", i.e. able to pass all tests first time but not a second (or 100th time), don't you need to think about why you have these doubts, and address them?

但我会质疑是否需要这样做,正如 Jolta 在他的评论中所说:如果没有代码改变,为什么需要重新测试?如果您对第三方输入有疑问,我会说您需要在您的应用程序代码中考虑到这一点。如果您担心您的代码可能“不稳定”,即第一次能够通过所有测试,但不能通过第二次(或第 100 次),难道您不需要考虑为什么会有这些疑问并解决它们吗?

Personally I think this is a (very minor) design fault in Gradle: if everything is completely up-to-date, rather than going "BUILD SUCCESSFUL" it should say "NO CHANGE SINCE LAST SUCCESSFUL BUILD: NOTHING DONE".

我个人认为这是 Gradle 中的一个(非常小的)设计错误:如果一切都完全是最新的,而不是“构建成功”,它应该说“自上次成功构建以来没有变化:没有完成”。

回答by mkobit

This was recently the topic on Gradle's blog post Stop rerunning your tests. The authorshows an example using outputs.upToDateWhen { false }and explains why it is wrong:

这是最近 Gradle 博客文章停止重新运行测试的主题。在笔者给出了一个例子使用outputs.upToDateWhen { false },并解释为什么它是错误的:

This doesn't actually force reruns

What the author of this snippet probably wanted to say is “Always rerun my tests”. That's not what this snippet does though. It will only mark the task out-of-date, forcing Gradle to recreatethe output. But here's the thing, if the build cache is enabled, Gradle doesn't need to run the task to recreate the output. It will find an entry in the cache and unpack the result into the test's output directory.

The same is true for this snippet:

test.dependsOn cleanTest

Gradle will unpack the test results from the build cache after the output has been cleaned, so nothing will be rerun. In short, these snippets are creating a very expensive no-op.

If you're now thinking “Okay, I'll deactivate the cache too”, let me tell you why you shouldn't.

这实际上并不强制重新运行

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

这段代码也是如此:

test.dependsOn cleanTest

Gradle 会在输出被清除后从构建缓存中解压测试结果,因此不会重新运行任何内容。简而言之,这些片段正在创建一个非常昂贵的空操作。

如果您现在想“好吧,我也会停用缓存”,让我告诉您为什么不应该这样做。

Then, the author goes on to explain why rerunning some tests is a waste of time:

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

The vast majority of your tests should be deterministic, i.e. given the same inputs they should produce the same result.

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

In the few cases where you do want to rerun tests where the code has not changed, you should model them as an input. Here are both examples from the blog post that show adding an input so the task will use it during its up-to-date checks.

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

task randomizedTest(type: Test) {
  systemProperty "random.testing.seed", new Random().nextInt()
}


task systemIntegrationTest(type: Test) {
  inputs.property "integration.date", LocalDate.now()
}

I recommend reading the entire blog post.

我建议阅读整个博客文章。

回答by masc3d

--rerun-tasksworks, but is inefficient as it reruns all tasks.

--rerun-tasks工作,但效率低下,因为它重新运行所有任务。

cleanTestby itself may not suffice due to build cache.

cleanTest由于构建缓存,它本身可能不够。

so, best way to accomplish this is:

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

./gradlew --no-build-cache cleanTest test

回答by Topera

TL;DR

TL; 博士

test.dependsOn cleanTest