我正在使用 Gradle 2.14.1 和 https://github.com/unbroken-dome/gradle-testsets-plugin添加集成测试任务。我想配置 HTML 报告的位置。 默认任务使用:
<project>/build/reports/tests
测试集插件配置:
<project>/build/intTest
对于 intTest
任务,我想要:
<project>/build/reports/test
<project>/build/reports/intTest
这是我的配置:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.unbroken-dome.gradle-plugins:gradle-testsets-plugin:1.2.0'
}
}
apply plugin: 'java'
apply plugin: 'org.unbroken-dome.test-sets'
defaultTasks = ['clean', 'build']
tasks.withType(Test) {
reports.html.destination = new File(project.reportsDir, name)
println(it.name + '\t' + reports.html.destination)
}
task wrapper(type: Wrapper) {
description = 'Defines the common gradle distribution for this project.'
gradleVersion = '2.14.1'
}
testSets {
intTest
}
intTest.dependsOn test
check.dependsOn intTest
repositories {
jcenter()
}
dependencies {
testCompile 'junit:junit:4.12'
intTestCompile 'junit:junit:4.12'
}
println('===== final config =====')
println(test.name + '\t' + test.reports.html.destination)
println(intTest.name + '\t' + intTest.reports.html.destination)
(请暂时忽略println
语句。)
完整构建后,intTest
任务的报告位于错误的位置(默认),并且应用了标准 test
任务的配置:
$ ls build/
classes dependency-cache intTest intTest-results libs reports test-results tmp
$ ls build/reports/
test
我添加了一些输出来查看发生了什么,这看起来很奇怪(项目的根目录是“blob”):
test /home/wujek/blob/build/reports/test
intTest /home/wujek/blob/build/reports/intTest
===== final config =====
test /home/wujek/blob/build/reports/test
intTest /home/wujek/blob/build/intTest
因此,在 tasks.withType()
block 中,报告的位置是正确的,但最终并非如此。
请注意,将 tasks.withType()
block 移到 testSets
block 之后适用于该项目,但我的实际设置是模式复杂的:我有多个模块,根 build.gradle
使用 subprojects
block 和 tasks.withType()
block 来配置所有模块的报告位置,然后其中一个子模块添加了一个新的测试集,并且其测试任务的 HTML 报告的位置错误。为了解决这个问题,我必须在添加测试集的子模块中重复配置。
这是怎么回事?为什么 tasks.withType()
block 说配置有效,但实际上却不起作用?
最佳答案
这是由于 Gradle 中排序配置的特殊性造成的。让我们浏览一下您的代码,Gradle 会对其进行处理,看看会发生什么(跳过不相关的行):
apply plugin: 'org.unbroken-dome.test-sets'
这会执行测试集插件的 apply 方法,其中包括 the creation of a class which listens for test sets to be added 。 It adds a whenObjectAdded
action到 testSets
容器。您尚未添加任何测试集,因此让我们返回到您的 build.gradle
。
tasks.withType(Test) {
reports.html.destination = new File(project.reportsDir, name)
println(it.name + '\t' + reports.html.destination)
}
您现在已经添加了一个操作,该操作将应用于所有现有的测试
任务以及创建的新任务。现在一切都展开了:
testSets {
intTest
}
这将创建一个名为 intTest
的 testSet
。测试集插件中的 whenObjectAdded
操作现在触发:
intTest
设置测试任务 is created .- 您的
withType
操作会触发,因为现在有一个新的Test
任务。这会将报告设置为您想要的位置。 whenObjectAdded
操作现在继续,到达 this line它还设置 html 报告位置,覆盖您刚刚设置的内容。
当您更改此设置以首先声明 testSet
时,它会:
whenObjectAdded
- 创建测试任务whenObjectAdded
- 设置测试任务的 HTML 报告位置withType
由您注册withType
触发将 HTML 报告位置设置为您所需的目标
没有硬性规则可以避免这种情况,因为插件可以并且确实采用截然不同的方法来注册其配置操作。一般来说,我尝试按以下顺序分解 build.gradle:
- Buildscript block (如果需要)
- 应用插件
- 设置项目级别属性(组、版本、源兼容性等)
- 配置扩展(源集、测试集、配置、依赖项)
- 配置任务(直接或 withType)
通常这有助于允许触发配置的插件在我的配置进行更改之前注册默认值。
仅供引用,Gradle's new, and still incubating, model space旨在帮助解决此配置排序问题。它并不完美,但可以让顺序更加明确。
关于Gradle `tasks.withType()` 之后添加的任务的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38621330/