Android代码质量管理平台搭建

Jacoco & SonarQube

  • JaCoCo是一个Java代码覆盖率库,它可以帮助开发人员了解他们的代码库中哪些代码已经被测试覆盖,哪些代码还需要进行测试。JaCoCo可以与各种构建工具(如Maven和Gradle)集成,以生成代码覆盖率报告。
  • SonarQube是一个开源的代码质量管理平台,它可以帮助开发人员在整个开发周期中管理和提高代码质量。SonarQube可以与各种编程语言(如Java、C#、JavaScript等)集成,并提供了一系列功能,包括代码质量分析、代码覆盖率、代码复杂度、代码重复性、安全漏洞等方面的检测。 我们要利用这2个工具平台,使用构建工具Gradle给Android项目打造一个可视化代码覆盖率,首先,使用JaCoCo生成代码覆盖率报告,然后将报告传递给SonarQube进行分析。SonarQube将使用这些报告来提供更广泛的代码质量分析,包括代码复杂度、代码重复性、安全漏洞等方面的检测。

Jacoco集成到Gradle

  1. 添加plugin classpath "org.jacoco:org.jacoco.core:0.8.10"

  2. 创建一个jacoco.gradle文件在需要单元测试覆盖的module里面

  3. 粘贴和修改如下代码,注意可以配置输出报告忽略文件和文件夹的覆盖率,通常是View层和一些工具类等

    groovy 复制代码
     apply plugin: "jacoco"
    
     jacoco {
         toolVersion = '0.8.10'
     }
    
     // 配置需要忽略单元测试覆盖率的文件或文件夹
     //* 匹配零个或多个字符
     //** 匹配零个或多个目录
     //? 匹配单个字符
     project.ext.coverageExclusions = [
             '**/BR.*',
             '**/R.*',
             '**/R$*.*',
             '**/Manifest*.*',
             "**/*Test*.*",
             '**/BuildConfig.*'
     ]
    
     def javaDebugTree = fileTree(dir: "${buildDir}/intermediates/javac/debug", excludes: coverageExclusions)
     def kotlinDebugTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/debug", excludes: coverageExclusions)
    
     task jacocoTestReport(type: JacocoReport, dependsOn: "testDebugUnitTest") {
         group = "Reporting"
         description = "Generate Jacoco coverage reports after running tests."
    
         reports {
             xml.getRequired().set(true)
             html.getRequired().set(true)
         }
    
         sourceDirectories.from = files(["${project.projectDir}/src/main/java"])
         classDirectories.from = files([javaDebugTree, kotlinDebugTree])
    
         // pattern '**/*' searches execution data in all sub-directories of build
         def execDataPatterns = ["**/*.exec", "**/*.ec"]
         executionData.from = files(fileTree(dir: "build", includes: execDataPatterns))
     }
  4. 在需要的module的build.gradle中添加apply from: "jacoco.gradle"

  5. 执行命令 ./gradlew :module clean jacocoTestReport

  6. 单元测试全部成功后,检查文件夹 build/reports/jacoco/jacocoTestReport/是否存在

  7. 右键build/reports/jacoco/jacocoTestReport/html/index.html Open in -> Browser

  8. 根据包名展示当前代码覆盖的详细情况,点击包名可以查看java类的详情

SonarQube安装和部署

  1. 下载免费的社区版Community Edition: www.sonarqube.org/downloads/
  2. 检查是否安装和配置JDK的环境变量
  3. 解压并且打开目录/bin,控制台打开/bin/目录选择操作系统对应文件夹进入
  4. 在控制台执行启动命令 ./sonar.sh start,支持命令 { console | start | stop | force-stop | restart | status | dump }
  5. 浏览器输入127.0.0.1:9000进入登录页面,默认账户密码 admin/admin
  6. 生成 api Token, 右上角我的账户-> security -> Generate Tokens

SonarQube集成到Gradle

  1. 添加plugin

    groovy 复制代码
     dependencies {
         classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.0"
     }
  2. 在根目录build.gradle配置,把Jacoco的report输出路径配置到jacoco.xmlReportPaths

    groovy 复制代码
    apply plugin: 'org.sonarqube'
    sonarqube {
        properties {
            property "sonar.projectName", "MVI-Hilt"
            property "sonar.projectKey", "MVI-Hilt"
            property "sonar.modules", ":app, :mvi"
            property "sonar.host.url", "http://127.0.0.1:9000"
            property "sonar.token", "squ_11f5a8e2654358fefc45420da045f50ab2dde76b"
            property "sonar.sources", "src/main/java, src/debug/java"
            property "sonar.tests", "src/test/java, src/androidTest/java"
            property "sonar.binaries", "build/intermediates/javac/debug/classes"
            property "sonar.androidLint.reportPaths", "build/reports/lint-results.xml"
            property "sonar.java.coveragePlugin", "jacoco"
            property "sonar.kotlin.coveragePlugin", "jacoco"
            property "sonar.junit.reportsPath", "build/reports/tests"
            property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/coverage/debug/report.xml, build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml"
        }
    }
  3. 在Android Studio中直接点击sonarqube {...}左边的绿色➡️,或者在控制台运行 ./gradlew sonarqube

  4. 浏览器打开网页http://127.0.0.1:9000

  5. 点击项目可以查看扫描的报告详情,代码规范(code smell);代码漏洞;覆盖率;代码重复率等

  6. 项目配置github actions 或者jenkins ci/pipeline等,在提交PR之后PR中输出一份当前PR代码的报告,帮助Reivewer来检查当前代码是否有漏洞和代码规范问题。

Issue集锦

  1. 执行Task:sonarqube显示成功却没有任何反应,日志中输出Skipping SonarQube analysis: no properties configured, was it skipped in all projects? 解决方案:gradle.properties中删除org.gradle.unsafe.configuration-cache=true
  2. 执行Task: 报错 Can't add different class with same name: com/example/Xxx 解决方案:把报错的这个Class配置到 jacoco的Exclusions中,'com/example/**'

扩展阅读

代码质量管理,我们需要编写单元测试代码,之前的MVI系列文档中详细的介绍了Android中如何实现单元测试。另外在国内Android对单元测试等并没有很强的要求,很多开发者并不会写单元测试,这个时候官方的文档其实是最新和最权威,合适的学习途径也让我们事半功倍。 Android的MVI架构最佳实践(四):单元测试 - 掘金 (juejin.cn)

相关推荐
老衲不服34 分钟前
android 三方sdk minSdkVersion 兼容问题处理
android
dy171740 分钟前
element-plus表格默认展开有子的数据
前端·javascript·vue.js
android_xc4 小时前
Android Studio国内仓库配置
android·ide·android studio
alexhilton4 小时前
runBlocking实践:哪里该使用,哪里不该用
android·kotlin·android jetpack
2501_915918414 小时前
Web 前端可视化开发工具对比 低代码平台、可视化搭建工具、前端可视化编辑器与在线可视化开发环境的实战分析
前端·低代码·ios·小程序·uni-app·编辑器·iphone
2501_915106325 小时前
iOS 使用记录和能耗监控实战,如何查看电池电量消耗、App 使用时长与性能数据(uni-app 开发调试必备指南)
android·ios·小程序·uni-app·cocoa·iphone·webview
雨白5 小时前
深入解析 Android 多点触摸:从原理到实战
android
程序员的世界你不懂5 小时前
【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
java·前端·数据库
索迪迈科技5 小时前
网络请求库——Axios库深度解析
前端·网络·vue.js·北京百思可瑞教育·百思可瑞教育
gnip5 小时前
JavaScript二叉树相关概念
前端