Home | History | Annotate | Download | only in gradle
      1 /**
      2  * This script plugin is used to bundle the host test (e.g. Robolectric) results and dist it in
      3  * a location where TradeFed knows how to parse.
      4  *
      5  * - If a non-dist build is run with test, it will run the normal unit tests, failing the build if
      6  *   there are test failures.
      7  * - If a dist build is run with test (e.g. ./gradlew dist test), the build will ignore any test
      8  *   failures, and will create a zip of the XML test reports for each test run, and copy them to
      9  *   dist/host-test-reports for consumption by TradeFed.
     10  */
     11 
     12 apply plugin: 'dist'
     13 apply plugin: 'jacoco'
     14 
     15 // If unit tests are run as part of the build, dist the test XML reports to host-test-reports/*.zip
     16 android.unitTestVariants.all { variant ->
     17     def task = tasks.findByName('test' + variant.name.capitalize())
     18     gradle.taskGraph.whenReady { taskGraph ->
     19         // Ignore the failures, so the build continues even on test errors when the build is
     20         // running with 'dist'. (Usually as part of a build server build)
     21         task.ignoreFailures = taskGraph.hasTask(tasks.dist)
     22     }
     23 
     24     def junitReport = task.reports.junitXml
     25     if (junitReport.enabled) {
     26         // Create a zip file of the XML test reports
     27         def zipTask = tasks.create("zipResultsOf${task.name.capitalize()}", Zip) {
     28             from junitReport.destination
     29             archiveName = task.name + 'Result.zip'
     30             destinationDir = junitReport.destination.parentFile
     31         }
     32         task.finalizedBy zipTask
     33 
     34         // Copy the test reports to dist/host-test-reports
     35         // The file path and format should match GradleHostBasedTest class in TradeFed.
     36         tasks.dist.mustRunAfter zipTask
     37         dist.file zipTask.archivePath.path, "host-test-reports/${zipTask.archiveName}"
     38     }
     39 }
     40 
     41 /*
     42  * The section below adds code coverage to all the unitTest targets. By default, the jacoco plugin
     43  * only adds to the 'java' plugin and not the Android ones.
     44  *
     45  * For each unitTest task "fooUnitTest", a new target "fooUnitTestCoverage" will be generated for
     46  * to generate the jacoco report.
     47  */
     48 android.testOptions.unitTests.all {
     49     // Fix robolectric tests reporting 0 coverage on newer versions of the plugin.
     50     jacoco {
     51         includeNoLocationClasses = true
     52     }
     53 }
     54 
     55 // Define the main coverage task if it does not exist. This task generates coverage report for all
     56 // unit tests.
     57 def coverageTask = tasks.findByName('coverage') ?: tasks.create('coverage') {
     58     group = "Reporting"
     59     description = "Generate Jacoco coverage reports"
     60 }
     61 
     62 android.unitTestVariants.all { variant ->
     63     def testTaskName = "test${variant.name.capitalize()}"
     64     def testTask = tasks.findByName(testTaskName)
     65 
     66     // Create coverage task of form 'testFlavorCoverageUnitTestCoverage' depending on
     67     // 'testFlavorCoverageUnitTest'
     68     def jacocoTask = tasks.create("${testTaskName}Coverage", JacocoReport) {
     69         group = "Reporting"
     70         description = "Generate a Jacoco coverage report for robolectric tests on ${variant.name}."
     71 
     72         classDirectories = fileTree(
     73             dir: "${project.buildDir}/intermediates/classes/" +
     74                 "${variant.productFlavors[0].name}/${variant.buildType.name}",
     75             excludes: ['**/R.class',
     76                        '**/R$*.class',
     77                        '**/BuildConfig.*',
     78                        '**/Manifest*.*']
     79         )
     80 
     81         sourceDirectories = files(variant.testedVariant.sourceSets.collect { it.java.srcDirs })
     82         executionData = files("${project.buildDir}/jacoco/${testTaskName}.exec")
     83 
     84         reports {
     85             xml.enabled = true
     86             html.enabled = true
     87         }
     88     }
     89     jacocoTask.dependsOn testTask
     90 
     91     // Create a zip file of the HTML coverage reports
     92     def zipTask = tasks.create("zipResultsOf${jacocoTask.name.capitalize()}", Zip) {
     93         from jacocoTask.reports.html.destination
     94         archiveName = "${testTaskName}HtmlCoverage.zip"
     95         destinationDir = jacocoTask.reports.html.destination.parentFile
     96     }
     97     jacocoTask.finalizedBy zipTask
     98 
     99     // Copy the coverage reports to dist/host-test-coverage
    100     // The file path and format should match JacocoLogForwarder class in TradeFed.
    101     tasks.dist.mustRunAfter jacocoTask
    102     dist.file jacocoTask.reports.xml.destination.path, "host-test-coverage/${jacocoTask.name}.xml"
    103 
    104     tasks.dist.mustRunAfter zipTask
    105     dist.file zipTask.archivePath.path, "host-test-coverage/${zipTask.archiveName}"
    106 
    107     coverageTask.dependsOn(jacocoTask)
    108 }
    109