Gradle不会复制测试资源来构建

时间:2013-12-04 20:30:28

标签: java resources gradle

我有一个多项目gradle项目(spring web),具有以下布局:

springweb
 |    build.gradle
 |    settings.gradle
 |_____ services
 |         build.gradle
 |         src/main/java
 |         src/main/resources
 |         src/test/java
 |         src/test/resources
 |             create-data.sql
 |_____ web
 |         build.gradle
 |         src/main/java
 |         src/main/resources
 |         src/main/webapp
 |         src/test/java
 |         src/test/resources

当我尝试执行src / test / resources(init.sql)

下的内容时
commandLine 'psql', '-h', 'localhost', '-d', 'junit', '--username', 'junit', '-f' , sourceSets['test'].output.resourcesDir.toString() + '/create-data.sql'

它失败了,因为资源在构建目录中不可用:

/Users/me/dev/springweb/services/build/resources/test/create-data.sql: No such file or directory

在我的root build.gradle下面:

ext {
    springSecurityGroup = 'org.springframework.security'
    springSecurityVersion = '3.1.4.RELEASE'
    springGroup = 'org.springframework'
    springVersion = '3.2.5.RELEASE'
    hibernateGroup = 'org.hibernate'
    hibernateVersion = '4.2.7.SP1'
}

subprojects {
    apply plugin: 'java'
    apply plugin: 'eclipse'
    sourceSets.all{
        println output.classesDir
    }

    repositories {
        mavenCentral()
    }
}

和'services'build.gradle:

task createDb (type:Exec) { 
     println sourceSets['test'].output.resourcesDir.toString()
     commandLine 'psql', '-h', 'localhost', '-d', 'junit', '--username', 'junit', '-f' ,'/Users/me/dev/sip/sip/sip04/src/main/resources/create-table.sql'
}
task fillDb (type:Exec, dependsOn: 'createDb') {
     commandLine 'psql', '-h', 'localhost', '-d', 'junit', '--username', 'junit', '-f' , sourceSets['test'].output.resourcesDir.toString() + '/create-data.sql'
}
test.dependsOn fillDb

dependencies {
    /* zipped */
}

/* Change context path (base url). otherwise defaults to name of project */

我用gradle build执行它:

gradle build
/Users/me/dev/springweb/services/build/classes/main
/Users/me/dev/springweb/services/build/classes/test
/Users/me/dev/springweb/web/build/classes/main
/Users/me/dev/springweb/web/build/classes/test
/Users/me/dev/springweb/services/build/resources/test
:services:compileJava UP-TO-DATE
:services:processResources UP-TO-DATE
:services:classes UP-TO-DATE
:services:jar UP-TO-DATE
:services:assemble UP-TO-DATE
:services:createDb
DROP TABLE
DROP SEQUENCE
zipped
:services:fillDb/Users/me/dev/springweb/services/build/resources/test/create-data.sql: No such file or directory

从输出中我了解到sourceSets正如我所期望的那样,但是不会复制测试资源。有什么问题?

2 个答案:

答案 0 :(得分:2)

通过Java插件中的processTestResources任务完成测试资源的复制。 Java插件还将此指定为测试任务的先决条件,以便在测试运行之前发生。

你告诉gradle你的fillDb任务也是测试任务的先决条件但是你没有告诉它processTestResources是你的createDb任务的先决条件。

所以你可以做类似

的事情
task createDb (type:Exec, dependsOn: 'processTestResources') { 
...

BTW测试资源是通过类路径提供给测试的东西。我假设您的测试实际上并不需要在运行时在类路径上提供您的sql,所以他们甚至需要在那里吗?

答案 1 :(得分:1)

Gradle使用processTestResources插件中的java任务来生成测试资源。默认情况下,测试资源在Module/build/resources/test中的位置。 如果您只想测试是否正确生成了testResources 运行以下命令:

./gradlew :<Module-name>:processTestResources 

运行命令后,检查testReources目录。它应该包含正确的文件。

另一个建议 尝试隔离gradle插件中的所有常见逻辑,并为Gradle插件编写测试。这样,您可以对这段代码充满信心。是否正常。

例如: TestPlugin.groovy

 project.sourceSets {
            test {
                resources {
                    srcDir project.files("${project.projectDir}/<location-of-resources>/")
                }
            }
        }

在这种情况下,请将您的资源放置在一个名为tempFile的文件夹中,以作为测试资源。 和测试相同: TestPluginSpec.groovy

 @Rule
    TemporaryFolder testProjectDir = new TemporaryFolder()
    File tempFile
    tempFile = testProjectDir.newFile('tempFile')
    buildFile = testProjectDir.newFile('build.gradle')

    buildFile << """
             plugins {
                id 'java'
               }
   """
def "should add test Resources into build/resources/test"(){
        when:
        def result = GradleRunner.create().withProjectDir(testProjectDir.root).withPluginClasspath().withArguments('processTestResources').withDebug(true).build()
        then:
        result.task(":processTestResources").outcome == TaskOutcome.SUCCESS
        and:
        Files.exists(Paths.get("${testProjectDir.root.path}/build/resources/test/tempFile"))
    }