如何通过脚本获取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
相关产品推荐
相关产品推荐

