首页 文章

Android Studio中的Jacoco代码覆盖范围

提问于
浏览
17

我一直试图在一段时间内安静地进行Jacoco测试覆盖 . 我在这些主题中尝试了几种可能的解决方案:

Android test code coverage with JaCoCo Gradle plugin

How do I get a jacoco coverage report using Android gradle plugin 0.10.0 or higher?

我使用genymotion在一个emulatated设备中运行测试 . 这是我添加到build.gradle的内容:

apply plugin: 'jacoco'

android{       
    jacoco {
        version "0.7.1.201405082137"
    }        
    buildTypes{
        debug{
                    testCoverageEnabled = true
        }
    }
}

jacoco {
    toolVersion "0.7.1.201405082137"
}

为了运行它,我使用类似的东西

./gradlew clean
./gradlew createFLAVOR_NAMEDebugCoverageReport

相关生成的文件/文件夹是:

/build/intermediates/coverage-instrumented-classes
/build/intermediates/jacoco
/build/outputs/code-coverage/connected/flavors/MyFlavor/coverage.ec

但是,没有@ build / reports / jacoco / test / html / index.html或任何html页面/代码覆盖率报告@ / build / outputs .

我还尝试创建一个专门的任务来构建一个覆盖率报告:

def coverageSourceDirs = [
    'src/main/java',
]

task jacocoTestReport(type: JacocoReport, dependsOn: "connectedAndroidTestFLAVOR_NAMEDebug") {
    group = "Reporting"
    description = "Generate Jacoco coverage reports after running tests."
    reports {
        xml.enabled = true
        html.enabled = true
    }
    classDirectories = fileTree(
        dir: './build/intermediates/classes/debug',
        excludes: ['**/R*.class',
                   '**/*$InjectAdapter.class',
                   '**/*$ModuleAdapter.class',
                   '**/*$ViewInjector*.class'
        ])
    sourceDirectories = files(coverageSourceDirs)
    executionData = files("$buildDir/jacoco/connectedAndroidTestMyFlavorDebug.exec")
    // Bit hacky but fixes https://code.google.com/p/android/issues/detail?id=69174.
    // We iterate through the compiled .class tree and rename $$ to $.
    doFirst {
       new File("$buildDir/intermediates/classes/").eachFileRecurse { file ->
            if (file.name.contains('$$')) {
                file.renameTo(file.path.replace('$$', '$'))
            }
        }
    }
}

然后 ./gradlew clean./gradlew jacocoTestReport . 输出与上面相同,因此,没有带覆盖报告的html页面或任何其他覆盖文件 .

我目前正在使用Android Studio v1.0.2和最新的gradle版本 . 我是一个相当新的gradle,所以我可能会遗漏一些基本的东西 .

谢谢

2 回答

  • 10

    在花了一整天追逐这个问题后,我发现's the problem. Contrary to the examples i'看到testDebug构建生成的文件不是.exec文件@991768_ .

    使用我的gradle和studio版本生成的文件是.ec @ build/outputs/code-coverage/connected/flavors/myFlavor/coverage.ec

    我没有找到任何与此相关的相关信息 . 然而,这可能是最近的更改,通过创建自定义JacocoReport任务并相应地更改executionData变量我已经解决了问题 . 这是我的实施:

    task jacocoTestReport(type: JacocoReport) {
    
      def coverageSourceDirs = [
            'src/main/java'
      ]
    
      group = "Reporting"
      description = "Generates Jacoco coverage reports"
      reports {
          xml{
              enabled = true
              destination "${buildDir}/reports/jacoco/jacoco.xml"
          }
          csv.enabled false
          html{
              enabled true
              destination "${buildDir}/jacocoHtml"
          }
      }
    
      classDirectories = fileTree(
              dir: 'build/intermediates/classes',
              excludes: ['**/R.class',
                         '**/R$*.class',
                         '**/BuildConfig.*',
                         '**/Manifest*.*',
                         '**/*Activity*.*',
                         '**/*Fragment*.*'
              ]
      )
    
      sourceDirectories = files(coverageSourceDirs)
      additionalSourceDirs = files(coverageSourceDirs)
      executionData = files('build/outputs/code-coverage/connected/flavors/smartcompanion/coverage.ec')
    }
    
  • 0

    使用Jacoco和Android Flavors的测试覆盖率报告:

    让我们考虑一下名为“免费”和“付费”的口味

    • Step1 :在项目模块目录(默认为应用程序)中创建文件jacoco.gradle,其中存在build.gradle,它应该在build.gradle文件旁边 . 目录结构如下图所示

    app> jacoco.gradle

    • Step 2 :在我们在步骤1中创建的文件中粘贴下面的代码,代码有自解释的注释要理解
    apply plugin: 'jacoco'
    
    jacoco {
        toolVersion = "0.7.5.201505241946"
    }
    project.afterEvaluate {
        // Grab all build types and product flavors
        def buildTypes = android.buildTypes.collect { type ->
            type.name
        }
        def productFlavors = android.productFlavors.collect { flavor ->
            flavor.name
        }
        // When no product flavors defined, use empty
        if (!productFlavors) productFlavors.add('')
    
        //iterate over the flavors
    
        productFlavors.each {
    
            productFlavorName ->
    //iterate over build types like debug,release,prod etc.
            buildTypes.each {
    
                buildTypeName ->
                    //sourceName — e.g. freeDebug ,sourcePath — e.g. free/debug
                def sourceName, sourcePath
                if (!productFlavorName) {
                    sourceName = sourcePath = "${buildTypeName}"
                } else {
                    sourceName = "${productFlavorName}${buildTypeName.capitalize()}"
                    sourcePath = "${productFlavorName}/${buildTypeName}"
                }
                    // testTaskName —  e.g. testFreeDebugtest task that the coverage task depends on,
                def testTaskName = "test${sourceName.capitalize()}UnitTest"
                // Create coverage task of form 'testFlavorTypeCoverage' depending on 'testFlavorTypeUnitTest'
                task "${testTaskName}Coverage" (type:JacocoReport, dependsOn: "$testTaskName") {
                    group = "Reporting"
                    description = "Generate Jacoco coverage reports on the ${sourceName.capitalize()} build."
                    classDirectories = fileTree(
                            dir: "${project.buildDir}/intermediates/classes/${sourcePath}",
                            excludes: [
                                    '**/R.class',
                                    '**/R$*.class',
                                    '**/*$ViewInjector*.*',
                                    '**/*$ViewBinder*.*',
                                    '**/BuildConfig.*',
                                    '**/Manifest*.*'
                            ]
                    )
                    def coverageSourceDirs = [
                            "src/main/java",
                            "src/$productFlavorName/java",
                            "src/$buildTypeName/java"
                    ]
                    additionalSourceDirs = files(coverageSourceDirs)
                    sourceDirectories = files(coverageSourceDirs)
                    executionData = files("${project.buildDir}/jacoco/${testTaskName}.exec")
                    reports {
                        //enables and disable the type of file you need
                        xml.enabled = false
                        html.enabled = true
                    }
                }
            }
        }
    }
    
    • 步骤3:在android studio终端下面运行命令来构建应用程序

    ./gradlew清洁组装

    • 步骤4:on build sucessfull,运行以下命令生成测试报告(将字符串“testFreeDebugUnitTestCoverage”更改为您的特定flavor / build类型,例如对于付费版本命令将为./gradlew testPaidDebugUnitTestCoverage)

    ./gradlew testFreeDebugUnitTestCoverage

    • Step 5 :

    它应该在终端给出成功消息,现在转到目录

    >app > build > reports >jacoco >${testName} >look for html or xml file report file
    
    • Step 6: 现在您可以在浏览器中打开并查看html测试覆盖率文件

    最好的运气!

相关问题