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

如何通过脚本获取Android Kotlin项目单元测试代码覆盖率并集成CI/CD

Android Kotlin项目单元测试代码覆盖率自动化实现(CI/CD集成)

一、项目基础配置(Jacoco插件)

Android项目通常用Jacoco做代码覆盖率统计,先在模块级build.gradle.kts(一般是app/build.gradle.kts)里完成配置:

1. 引入Jacoco插件

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("jacoco") // 加入Jacoco覆盖率插件
}

2. 开启Debug模式下的覆盖率收集

android {
    buildTypes {
        debug {
            testCoverageEnabled = true // 只在Debug环境开启,避免影响Release构建
        }
    }

    testOptions {
        unitTests.all {
            // 适配无位置信息的类(比如Kotlin协程相关)
            it.jacoco.includeNoLocationClasses = true
            // 排除无关类,避免统计SDK、测试框架代码
            it.jacoco.excludes = listOf("org.junit.*", "android.*", "kotlin.*")
        }
    }
}

3. 自定义Jacoco报告生成任务

添加任务来生成HTML/XML格式的覆盖率报告:

tasks.register<JacocoReport>("jacocoTestReport") {
    // 先执行单元测试任务
    dependsOn("testDebugUnitTest")

    // 指定覆盖率数据文件路径
    executionData.setFrom(fileTree(project.buildDir).include(
        "jacoco/testDebugUnitTest.exec",
        "outputs/code-coverage/connected/*coverage.ec"
    ))

    // 指定要统计的源代码目录
    sourceDirectories.setFrom(
        files("$projectDir/src/main/java"),
        files("$projectDir/src/main/kotlin")
    )
    // 指定编译后的类文件目录,排除不需要统计的类
    classDirectories.setFrom(fileTree("$projectDir/build/intermediates/javac/debug/classes").apply {
        exclude(
            "**/R.class",
            "**/R$*.class",
            "**/BuildConfig.*",
            "**/Manifest*.*",
            "**/*Test*.*" // 排除测试类本身
        )
    })

    // 配置报告输出格式和路径
    reports {
        html.required.set(true) // HTML报告,方便可视化查看
        xml.required.set(true) // XML报告,供CI工具解析(比如SonarQube)
        csv.required.set(false)
        html.outputLocation.set(file("$projectDir/build/reports/jacoco/jacocoTestReport/html"))
        xml.outputLocation.set(file("$projectDir/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml"))
    }
}

二、本地执行脚本

写一个Shell脚本(比如generate_coverage.sh),方便本地测试和CI调用:

#!/bin/bash

# 清理旧构建产物
./gradlew clean

# 执行单元测试并生成覆盖率报告
./gradlew jacocoTestReport

# 检查报告是否生成成功
if [ -d "./app/build/reports/jacoco/jacocoTestReport/html" ]; then
    echo "覆盖率报告生成完成,路径:./app/build/reports/jacoco/jacocoTestReport/html/index.html"
else
    echo "覆盖率报告生成失败,请查看构建日志排查问题"
    exit 1
fi

给脚本加执行权限:chmod +x generate_coverage.sh,本地运行./generate_coverage.sh即可生成报告。

三、CI/CD流水线集成

1. GitHub Actions示例

在项目根目录创建.github/workflows/coverage.yml:

name: Unit Test Coverage

on: [push, pull_request]

jobs:
  coverage:
    runs-on: ubuntu-latest
    steps:
      - name: 拉取代码
        uses: actions/checkout@v4

      - name: 配置JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: 给gradlew加执行权限
        run: chmod +x gradlew

      - name: 生成覆盖率报告
        run: ./gradlew jacocoTestReport

      - name: 上传报告作为构建产物
        uses: actions/upload-artifact@v4
        with:
          name: jacoco-coverage-report
          path: app/build/reports/jacoco/jacocoTestReport/html/

代码推送或PR触发时,自动运行单元测试并生成报告,还会把报告上传供下载查看。

2. GitLab CI示例

在项目根目录创建.gitlab-ci.yml:

unit-test-coverage:
  image: openjdk:17-jdk-slim
  stage: test
  before_script:
    - chmod +x gradlew
  script:
    - ./gradlew clean jacocoTestReport
  artifacts:
    paths:
      - app/build/reports/jacoco/jacocoTestReport/html/
    expire_in: 7 days

四、常见问题处理

  • 覆盖率统计不全:检查classDirectories是否包含所有编译后的类文件,确认排除规则没有误删需要统计的类。
  • CI构建失败:确保CI环境的JDK版本和项目一致(建议用JDK 17适配最新Android Gradle插件)。
  • 设置覆盖率阈值:如果需要强制最低覆盖率,可添加验证任务:
tasks.withType<JacocoCoverageVerification> {
    dependsOn("jacocoTestReport")
    violationRules {
        rule {
            limit {
                minimum = 0.7.toBigDecimal() // 要求至少70%的代码覆盖率
            }
        }
    }
}

执行./gradlew jacocoCoverageVerification,不达标会终止构建。

内容的提问来源于stack exchange,提问作者Abhiroop Nandi Ray

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 17:37:41