Gradle执行processTestResources未复制全部测试资源,是否为Bug?
Gradle processTestResources仅复制部分测试资源问题
我有一个Gradle项目,执行processTestResources或test任务时,Gradle并未将全部测试资源复制到输出目录。制作了简化测试用例,目录结构如下:
gradle/ # 包含Gradle wrapper文件 src/ hello/ Hello.java tests/ hello/ hello.txt foo/ bar.txt build.gradle gradlew gradle.bat
build.gradle内容:
apply plugin: 'java' sourceSets { main { java.srcDirs = ['src'] resources.srcDirs = ['src'] resources.excludes = ['**/*.java'] } test { java.srcDirs = ['tests'] resources.srcDirs = ['tests'] resources.excludes = ['**/*.java'] } } task staging (type: Copy) { from processResources from processTestResources { include 'foo/' } // 问题行 into "${buildDir}/staging" } task run (type: JavaExec) { dependsOn staging // [...] }
执行命令:
./gradlew processTestResources # 或直接执行 ./gradlew test
现象:仅tests/foo下的资源被复制到输出目录,tests/hello下的资源未被复制。但如果注释staging任务中标记为“问题行”的代码,所有测试资源都会正常复制。
我并未运行staging任务,但Gradle似乎因该任务的配置判断仅需复制tests/foo的资源,这是Gradle的预期行为还是Bug?
官方结论
这是Gradle的预期行为,并非Bug。相关GitHub Issue已关闭,官方解释核心点:
- Gradle的配置阶段会处理所有任务的配置,即使你没有执行某个任务,它的配置代码依然会被执行。
- 在staging任务中,
from processTestResources { include 'foo/' }这种写法,本质是直接修改了processTestResources任务本身的配置,给它添加了include 'foo/'的过滤规则——这个修改会全局生效,不管你是否执行staging任务。
解决方案
如果需要在staging任务中仅复制processTestResources的部分内容,不要直接修改processTestResources任务的配置,而是从它的输出目录中进行过滤,修改staging任务的代码如下:
task staging (type: Copy) { from processResources from "${processTestResources.destinationDir}" { include 'foo/' } into "${buildDir}/staging" }
这样只会在staging任务复制时应用过滤规则,不会影响processTestResources本身的执行逻辑,执行processTestResources或test任务时就会复制全部测试资源了。
内容的提问来源于stack exchange,提问作者Grodriguez
相关产品推荐
相关产品推荐

