Gradle测试任务 - Gradle 1.6和Gradle 2.3或更高版本

时间:2015-07-08 03:17:08

标签: unit-testing gradle jacoco gradle-2

我有一个Java项目。

PS :在我的项目中,我没有 src / test / java 中的任何java程序/源代码。
- 此文件夹只包含一个blank.txt文件。

我有两种不同的Gradle版本:

  1. Gradle 1.6 with Java 7(因为Java 8与Gradle 1.6不兼容或任何版本<小于1.10版本,如果我正确的话)。

  2. 另一个版本是:Gradle 2.3 with Java 8。

  3. 使用上述两种Gradle 1.6 + Java7 OR Gradle 2.3 + Java 8版本我的项目构建成功

    虽然,我注意到一件事:在运行构建时,它会调用" test"任务自动(根据Gradle设计,测试任务免费运行);我在Gradle 1.6 + Java7运行期间发现---我看到以下输出。

    :jar
    :assemble
    :compileTestJava UP-TO-DATE
    :processTestResources
    :testClasses
    :test
    :check
    

    正如您所注意到的,它说我没有任何测试源代码(即src / test / java不包含任何源代码 OR 那里&# 39;对于Gradle来说,这次编译并不是什么新鲜事自上次gradle运行构建以来可能没有任何改变)这就是为什么compileTestJava任务显示 UP-TO-DATE < / strong>在它面前。

    但是,:测试任务显示它已成功运行。我在test {..}任务中使用了jacoco(代码覆盖)部分,然后它实际运行了那部分(因为在 test 任务之前没有UP-TO-DATE)。 Jacoco部分未在我的项目的build.gradle中定义,但实际上它来自顶级/ GRADLE_HOME / init.d / some-common-top-level.gradle文件(其中test {.. 。其中有jacoco {...} ..}部分。)

    正如我上面提到的,测试任务并没有说UP-TO-DATE,因此,在Gradle构建过程完成后,我可以看到它在里面创建了以下文件夹/文件结构 build / tmp / expandedArchives / org.jacoco .... 文件夹:

    $ ls -ltr build/tmp/expandedArchives/
    total 4
    drwxr-xr-x+ 1 e020001 Domain Users 0 Jul  7 20:45 org.jacoco.agent-0.7.2.201409121644.jar_778m6tp3jrtvcetasufl59dmau
    
    $ ls -ltr build/tmp/expandedArchives/org.jacoco.agent-0.7.2.201409121644.jar_778m6tp3jrtvcetasufl59dmau/
    total 272
    drwxr-xr-x+ 1 e020001 Domain Users      0 Jul  7 20:58 META-INF
    -rwxr-xr-x  1 e020001 Domain Users   2652 Jul  7 20:58 about.html
    -rwxr-xr-x  1 e020001 Domain Users 272311 Jul  7 20:58 jacocoagent.jar
    drwxr-xr-x+ 1 e020001 Domain Users      0 Jul  7 20:58 org
    

    当我运行Gradle 2.3和Java8时,情况并非如此。

    构建成功但我没有获得包含jacocoagent.jar文件的build / tmp / expandedArchives / org.jacoco ....文件夹。

    任何想法,为什么Gradle 2.3没有创建这个特定于jacoco的.jar文件。

    使用Gradle 2.3 + Java8,以下输出显示在:compileTestJava :test 任务前面的UP-TO-DATE(Gradle不是这种情况) 1.6 for test 任务)。

    我跑了&#34; gradle clean build &#34;。

    :compileTestJava UP-TO-DATE
    :compileTestGroovy UP-TO-DATE
    :processTestResources
    :testClasses
    :test UP-TO-DATE
    :check
    

    我需要Gradle 2.3在build / tmp / expandedArchives / org.jacoco .....文件夹下生成这个jacocoagent.jar,以便我可以在下游Jenkins作业(运行非单元测试)中使用它,因为这样项目确实有一些集成测试,我在下游作业中从父主构建作业(运行 gradle clean build ,包括测试任务)中获取jacocoagent.jar,这样我就可以将它传递给启动Tomcat时TOMCAT JVM(这样我就可以获得针对IT测试的jacocoIT.exec代码覆盖率)。但是,在我切换到Gradle 2.3之后,所有我没有src / test / java的项目...现在jacocoagent.jar没有被创建,并且复制工件插件在尝试时失败了从父作业中复制.jar文件。

    还有一点
    使用Gradle 1.6 + Java7,如果我运行 gradle clean build ,它会在build / tmp / expandedArchives / org.jacoco .....文件夹中成功创建jacocoagent.jar,但它以这种方式工作,仅当我运行 gradle clean build 或&#34; gradle clean; gradle test &#34;。

    如果我运行gradle clean build,然后删除build / tmp文件夹,现在只运行: gradle test ,它会在:compileTestJava前面显示UP-TO-DATE :测试任务,并且不会创建包含jacocoagent.jar文件的build / tmp / expandedArchives / org.jacoco ....文件夹。

    有关详细信息,我在为Gradle 1.6 + java 7运行 gradle test 任务时附加配置文件运行(即使用 - 配置文件选项)。

    我在配置文件 html 文件中看到,当运行测试任务时,它首先按照Gradle流程逻辑调用compileJava,然后测试任务,然后执行#39 ; s还调用 depedencies --- :jacocoAgent (根据依赖关系解析选项卡): enter image description here


    使用Gradle 2.3 + Java8时,依赖关系解析/顺序和任务执行步骤与生成或显示对jacocoAgent依赖关系的任何引用不同(或者按照与Gradle 1.6相比的顺序),因为它甚至没有调用它。 enter image description here

    使用 -i (或 - info )选项运行 Gradle1.6 + Java7 测试任务显示为什么它运行测试任务,即使我没有测试源代码,请查看原因:

    Note: Recompile with -Xlint:unchecked for details.
    :processResources
    Skipping task ':processResources' as it has no source files.
    :processResources UP-TO-DATE
    :classes
    Skipping task ':classes' as it has no actions.
    :compileTestJava
    Skipping task ':compileTestJava' as it has no source files.
    :compileTestJava UP-TO-DATE
    :processTestResources
    Executing task ':processTestResources' due to:
      No history is available.
    :testClasses
    Skipping task ':testClasses' as it has no actions.
    :test
    file or directory '/my/workspace/project/build/classes/test', not found
    Executing task ':test' due to:
      No history is available.
    file or directory '/my/workspace/project/build/classes/test', not found
    Finished generating test XML results (0.001 secs)
    Generating HTML test report...
    Finished generating test html results (0.012 secs)
    
    BUILD SUCCESSFUL
    

2 个答案:

答案 0 :(得分:0)

无论输入和输出的状态如何,您都可以强制执行测试任务:

test{
    outputs.upToDateWhen{false}
}

对于早期的gradle版本,您可以通过

确保类目录存在
task createTestClassesDir << {sourceSets.test.output.classesDir.mkdirs()}
test.dependsOn createTestClassesDir

答案 1 :(得分:0)

要点:

使用Gradle 2.3,如果没有有效的.java / .groovy(或其他)测试代码,那么测试任务甚至不会运行,因此不会有jacocoagent.jar在build / tmp / exapandedArchives / org.jacoco.xxx ....文件夹的深处创建。

解决方案是在allprojects {....}部分中包含以下内容(在顶级$ GRADLE_HOME / init.d / some-global-file.gradle中)。我们所做的只是,如果src / test / java(标准)或任何遗留文件夹结构(src / java,如果您的项目结构是这样的)没有任何有效的测试源代码,那么我们可以添加一个虚拟测试文件(DummyTestXYZ.java或groovy)并让测试任务运行,它将生成jacocoagent.jar(我们可以使用/绑定Tomcat选项来生成非单元的集成测试的jacoco报告)。这样,如果您的主构建作业调用下游/子作业来运行您的IT测试,它就不会失败,因为它可以获取jacocoagent.jar(来自主构建作业的工作空间),因为测试任务将创建build / tmp / expandedArchives / org.jacoco.xx.x.xx..x文件夹中的jacocoagent.jar(您可以使用Jenkins中的Copy Artifact插件获得)。

PS :更改 if 语句逻辑acc。到您自己的文件夹设置,即您要在哪个文件夹中创建DummyTestXYZ.java文件。在我们的例子中,所有新项目都使用src / test / java(根据Maven / Gradle标准的标准文件夹结构),并且在新项目创建期间,我们将向源控件添加有效的样本单元测试。因此,在下面的逻辑中,我们实际上忽略了在src / test / java存在的情况下创建这个 DummyTestXYZ.java 并且仅当src / test / java文件夹不存在时才创建此文件在项目中(即这是一个具有遗留文件夹结构的项目)+ test / java(用于存储JUnit单元测试的遗留文件夹)没有.java程序和/或如果test / java不存在则先创建它然后创建虚拟文件。我知道,我们可以在Jenkins服务器上的某个位置上传jacocoagent.jar,并在启动Tomcat时使用该文件获取IT测试的代码覆盖率。我们添加的虚拟测试文件需要junit:junit:4.10或4.11库版本,以便:compileTestJava任务成功。

   compileJava {
    doLast {
        def dirName = "${projectDir}/test/java"

        if(!file( "${projectDir}/src/test/java" ).exists()) 
            if(!file( dirName ).exists()) 
                new File( dirName ).mkdirs()

        if(file( dirName ).exists()) {
            def javaCnt = new FileNameByRegexFinder().getFileNames(dirName, /.*\.java/).size()
            if(javaCnt == 0) {
                def f = new File( dirName , 'DummyTestXYZ.java' )
                def w = f.newPrintWriter()
                w.println('import org.junit.Test;')
                w.println('')
                w.println('public class DummyTestXYZ {')
                w.println('@Test' )
                w.println('public void test() {')
                w.println('}')
                w.println('}')
                w.close()
            }
        }
    }
   }

   test {
     doFirst {
              testResultsDirName = "test-results/UT"
              testReportDirName = "tests/UT"
     }         
     maxParallelForks = 5
     forkEvery = 50
     //ignoreFailures = true

     // Following Jacoco section is required only in Jenkins
     // But a developer can uncomment them if they want this feature to work for their 
     // Desktop local Gradle builds.
     jacoco {
            //Following vars works only with versions >= 1.7 version of Gradle
            destinationFile = file("$buildDir/jacoco/UT/jacocoUT.exec")
     }

     doLast {
        if (file("${projectDir}/test/java/DummyTestXYZ.java").exists()) {
            println "++"
            println "++"
            println "++"
            println "======================================================="
            println "DEV Team – Please add valid Unit tests in this project."
            println "======================================================="
            println "++"
            println "++"
            println "++"
            sleep(30 * 1000)
            new File("${projectDir}/build/classes/test").deleteDir()
            new File("${buildDir}/jacoco/UT").deleteDir()
            new File("${buildDir}/test-results/UT").deleteDir()
            delete "${projectDir}/test/java/DummyTestXYZ.java"
         }


     }
   }
   //Do the same (as above test code) for any other similar test tasks like integartionTest, acceptanceTest etc..

  jacocoTestReport {
     //cleaning any compile time generated (for ex: JiBx classes files) so that jacoco task won't fail for not finding the actual source files (.java/.groovy for the compile time generated .class files)
     doFirst {
         delete fileTree (dir: "${buildDir}/classes", include: "**/JiBX_*.class")
     }

     group = "Reporting"
     description = "Generate Jacoco coverage reports after running tests."
     //ignoreFailures = true

     executionData = fileTree(dir: 'build/jacoco', include: '**/*.exec')

     reports {
       xml{
         enabled true
         //Following value is a file
         destination "${buildDir}/reports/jacoco/xml/jacoco.xml"
       }
       csv.enabled false
       html{
         enabled true
         //Following value is a folder
         destination "${buildDir}/reports/jacoco/html"
       }
     }

     sourceDirectories = files(['src/java','src/main/java', 'src/main/groovy'])
     classDirectories =  files('build/classes/main')

     doLast {
        if (file("${projectDir}/test/java/DummyTestXYZ.java").exists()) {
            delete "${projectDir}/test/java/DummyTestXYZ.java"
         }
     }
   }