使用Jenkins + SonarQube + Jacoco实现Android测试覆盖率统计

Jacoco简介

JaCoCo is a free code coverage library for Java, which has been created by the EclEmma team based on the lessons learned from using and integration existing libraries for many years.

JaCoCo是一个免费的Java代码覆盖库,由EclEmma团队基于多年来使用和整合现有库的经验教训创建。

官网:https://www.eclemma.org/jacoco/index.html

开发环境

  • JaCoCo项目托管在 GitHub
  • JaCoCo支持的最低JRE版本是Java 1.5
  • SonarQube跟踪Jacoco源代码质量问题

Android项目使用Jacoco

jacoco-Android

Gradle插件为Android单元测试创建JaCoCo测试报告

https://github.com/arturdm/jacoco-android-gradle-plugin

Gradle中配置Jacoco

1.配置project/build.gradle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
buildscript {
repositories {
jcenter()
google()
}
dependencies {

// jacoco-android
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.2'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}

}

2.配置project/jacoco.gradle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//apply plugin: 'jacoco'
apply plugin: 'jacoco-android'

jacoco {
toolVersion = "0.7.7.201606060606"
reportsDir = file("$buildDir/JacocoReport")
}

/**
* Error:Cannot add task ':app:jacocoTestReport' as a task with that name already exists.
* 需要加overwrite: true
*/
//task jacocoTestReport(type: JacocoReport, dependsOn: 'testDebugUnitTest') {
task jacocoTestReport(type: JacocoReport, dependsOn: 'testDebugUnitTest',overwrite: true) {
group = "reporting"
reports {
xml.enabled = true
html.enabled = true
}

def debugTree = fileTree(dir: "${buildDir}/intermediates/classes/debug",
excludes: ['**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*$Lambda$*.*', // Jacoco can not handle several "$" in class name.
'**/*Module.*', // Modules for Dagger.
'**/*Dagger*.*', // Dagger auto-generated code.
'**/*MembersInjector*.*', // Dagger auto-generated code.
'**/*_Provide*Factory*.*',
'**/*_Factory.*', //Dagger auto-generated code
'**/*$*$*.*' // Anonymous classes generated by kotlin
])
def mainSrc = "${project.projectDir}/src/main/java"

sourceDirectories = files([mainSrc])
classDirectories = files([debugTree])
executionData = files("${buildDir}/outputs/code-coverage/connected/coverage.ec")

}

3.配置project/app/build.gradle

1
2
3
4
5
6
7
8
9
apply from: "$project.rootDir/jacoco.gradle"

android {
buildTypes {
debug {
testCoverageEnabled true
}
}
}

编写工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class MathUtil {

private MathUtil() {
throw new IllegalStateException("Utility class");
}

public static int max(int a, int b, int c) {
if (a > b) {
if (a > c) {
return a;
} else {
return c;
}
} else {
if (b > c) {
return b;
} else {
return c;
}
}
}

}

编写测试工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class MathUtilTest {

@Test
public void test_max_1_2_3() {
assertEquals(3, MathUtil.max(1, 2, 3));
}

@Test
public void test_max_1_3_2() {
assertEquals(3, MathUtil.max(1, 3, 2));
}

@Test
public void test_max_3_2_1() {
assertEquals(3, MathUtil.max(3, 2, 1));
}

@Test
public void test_max_0_0_0() {
assertEquals(0, MathUtil.max(0, 0, 0));
}

@Test
public void test_max_0_1_0() {
assertEquals(1, MathUtil.max(0, 1, 0));
}

}

源码来源:https://www.ibm.com/developerworks/cn/java/j-lo-jacoco/

查看结果

jacocoTestReport

右击运行,结果可在app\build\JacocoReport\jacocoTestDebugUnitTestReport\html\index.html中查看

Jenkins集成Jacoco

安装Jacoco插件

插件管理中搜索jacoco安装即可

配置构建

1
2
##jacocoTestReport 无数据
jacocoTestDebugUnitTestReport

jacocoTestDebugUnitTestReport

配置构建后操作

1.Record JaCoCo coverage report

Record JaCoCo coverage report

1
2
3
4
##**/outputs/code-coverage/connected/coverage.ec 无数据
**/build/jacoco/testDebugUnitTest.exec
**/build/intermediates/classes/debug
**/src/main/java

2.Publish Junit test result report

Publish Junit test result report

1
app/build/test-results/testDebugUnitTest/*.xml

查看测试报告结果

立即构建后在Test Result中查看

Test Result

SonarQube整合Jacoco

可以为SonarQube提供测试执行和代码覆盖率报告。

先决条件

Java插件将重用报表并不生成它们,因此在尝试配置分析以导入这些报表之前,需确保它们已正确生成,而不是空的。

  • 测试执行报告必须符合JUnit XML格式。
  • 代码覆盖率报告必须由JaCoCo生成。

配置Jacoco

在Jenkins项目中配置构建Execute SonarQube Scanner,新增jacoco配置

Execute SonarQube Scanner

1
2
sonar.core.codeCoveragePlugin=jacoco
sonar.jacoco.reportPath=app/build/jacoco/testDebugUnitTest.exec

立即构建

重新立即构建即可在SonarQube中查看覆盖率


相关主题