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 12apply plugin: 'dist' 13apply plugin: 'jacoco' 14 15// If unit tests are run as part of the build, dist the test XML reports to host-test-reports/*.zip 16android.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 */ 48android.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. 57def coverageTask = tasks.findByName('coverage') ?: tasks.create('coverage') { 58 group = "Reporting" 59 description = "Generate Jacoco coverage reports" 60} 61 62android.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