You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android项目Jacoco覆盖率报告仅统计单元测试,Instrumentation测试覆盖率为0%

Android Jacoco覆盖率报告未统计Instrumentation测试的问题解决

问题描述

在生成包含单元测试和Instrumentation测试的Android项目全局Jacoco覆盖率报告时,报告仅统计单元测试覆盖率,Instrumentation测试覆盖率显示为0%。相关配置及代码如下:

Gradle任务配置

task jacocoTestReport(type: JacocoReport, dependsOn: ["testDebugUnitTest", "createDebugAndroidTestCoverageReport", "connectedAndroidTest"]) {
    group = "Reporting"
    description = "Generate Jacoco coverage reports"

    reports {
        xml.required = true
        html.required = true
    }

    def fileFilter = ['**/AndroidManifest.xml', '**/strings.xml', '**/*.xml', '**/*.json']
    def mainSrc = "${project.projectDir}"
    def kotlinTree = fileTree(dir: "$project.buildDir/tmp/kotlin-classes/debugUnitTest", excludes: fileFilter)
    def kotlinUITree = fileTree(dir: "$project.buildDir/tmp/kotlin-classes/debugAndroidTest", excludes: fileFilter)
    sourceDirectories.setFrom(files([mainSrc]))
    classDirectories.setFrom(files([kotlinTree, kotlinUITree]))
    executionData.setFrom(fileTree(dir: "$project.buildDir",
            includes: ['**/*.exec', '**/*.ec']
    ))
}

执行命令

gradlew clean build
gradlew connectedAndroidTest jacocoTestReport

Instrumentation测试代码

@LargeTest
@RunWith(AndroidJUnit4::class)
class ExampleActivityTest {

    private lateinit var scenario: ActivityScenario<ExampleActivity>


    @Before
    fun setup() {
        scenario = ActivityScenario.launch(ExampleActivity::class.java)
        scenario.moveToState(Lifecycle.State.RESUMED)
    }

    @After
    fun postExecution() {
        scenario.moveToState(Lifecycle.State.DESTROYED)
    }

    @Test
    fun addTaxReceipt() {
        val fullName = "Carlos"
        
        onView(withId(R.id.edt_full_name))
            .perform(typeText(fullName))
            .perform(closeSoftKeyboard())

        val appContext = InstrumentationRegistry.getInstrumentation().targetContext
        assertEquals("com.example.project.android", appContext.packageName)
    }
}

解决方案

1. 修正Class目录指向

原配置中kotlinTree和kotlinUITree错误指向了测试代码的类文件目录,而非被测试的主项目类文件。需统一指向主项目的debug类目录:

def mainClasses = fileTree(dir: "$project.buildDir/tmp/kotlin-classes/debug", excludes: fileFilter)

2. 精准配置源码目录

原mainSrc直接使用项目根目录会包含大量无关文件,需指定具体源码路径:

def mainSrc = files("$project.projectDir/src/main/java", "$project.projectDir/src/main/kotlin")

3. 开启Instrumentation测试覆盖率收集

在Android闭包中添加配置,确保Instrumentation测试生成覆盖率数据:

android {
    buildTypes {
        debug {
            testCoverageEnabled true
        }
    }
}

4. 修改后的完整Jacoco任务

task jacocoTestReport(type: JacocoReport, dependsOn: ["testDebugUnitTest", "connectedAndroidTest"]) {
    group = "Reporting"
    description = "Generate Jacoco coverage reports"

    reports {
        xml.required = true
        html.required = true
    }

    def fileFilter = ['**/AndroidManifest.xml', '**/strings.xml', '**/*.xml', '**/*.json']
    def mainSrc = files("$project.projectDir/src/main/java", "$project.projectDir/src/main/kotlin")
    def mainClasses = fileTree(dir: "$project.buildDir/tmp/kotlin-classes/debug", excludes: fileFilter)

    sourceDirectories.setFrom(mainSrc)
    classDirectories.setFrom(mainClasses)
    executionData.setFrom(fileTree(dir: "$project.buildDir", includes: [
        "jacoco/testDebugUnitTest.exec",
        "outputs/code_coverage/debugAndroidTest/connected/*coverage.ec"
    ]))
}

5. 优化执行命令

无需单独执行clean build,直接运行以下命令即可:

gradlew clean jacocoTestReport

内容的提问来源于stack exchange,提问作者K_Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 15:45:30