Jenkins构建Android项目持续集成之单元测试及代码覆盖率
单元测试
在软件开发中一直在推崇TDD(测试驱动开发),但是一直不能被有效的执行或者并不是真正的测试驱动开发(先开发后写单元测试),因为我们懒!而Android开发又是大多应用层面的开发,很多都是和视图层紧密相连的,业务逻辑和view相绑定,这导致编写单元测试有相当大的困难,因此就我项目而言,只针对工具类、服务端API编写单元测试。关于android Studio如何编写单元测试并运行,可以看之前写的一篇文章Android Studio 单元测试
代码覆盖率
编写好单元测试后,我们需要知道,测试用例是否覆盖了代码的所有分支情况,这样才能保证代码的可靠性、正确性。
编写测试用例
如果使用Android Studio创建项目的话,那么默认的会在androidTest包下生成一个ApplicationTest类,在这里面可以写测试用例。
上图写的是一个SharedPreferences Util工具类的测试用例。
如果你的测试用例不想写在这个包下,想自定义,也可以在项目的build.gradle写如下的配置
android {
sourceSets {
androidTest{
java.srcDirs = ['src/com/helen/andbase/tests']
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
Gradle配置jacoco
Jacoco是一个开源的覆盖率工具。这里讲下gradle如何配置。
首先要在项目的build.gradle引入插件,语句如下:
apply plugin: 'jacoco'
- 1
- 1
然后注明使用的版本号
jacoco{
version "0.7.4.201502262128"
}
- 1
- 2
- 3
- 1
- 2
- 3
接着,申明一个gradle task
task jacocoTestReport(type:JacocoReport,dependsOn:"connectedAndroidTest"){
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
reports{
xml.enabled = false
html.enabled = true
csv.enabled = false
}
classDirectories = fileTree(
dir : "$buildDir/intermediates/classes/debug",
excludes : [
'**/*Test.class',
'**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*'
]
)
def coverageSourceDirs = ['src/main/java']
additionalSourceDirs = files(coverageSourceDirs)
sourceDirectories = files(coverageSourceDirs)
additionalClassDirs = files(coverageSourceDirs)
executionData = files("$buildDir/outputs/code-coverage/connected/coverage.ec")
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
最后,打开testCoverageEnabled,需要注意的是,打开该属性的话,在断点调试的时候会导致方法参数值丢失(看不到),所以在调试的时候要记得把它关掉。
buildTypes {
debug{
testCoverageEnabled true
}
}
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
完整的gradle配置如下
apply plugin: 'com.android.library'
//代码覆盖率插件
apply plugin: 'jacoco'
android {
compileSdkVersion 22
buildToolsVersion '22.0.1'
defaultConfig {
minSdkVersion 8
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug{
testCoverageEnabled true
}
}
lintOptions {
abortOnError false
}
packagingOptions {
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
}
jacoco{
version "0.7.4.201502262128"
}
}
//jacocoTestReport依赖于connectedAndroidTest task,所以在执行jacoco之前需要先执行connectedAndroidTest,也就是说需要连接测试机(模拟器or真机)
task jacocoTestReport(type:JacocoReport,dependsOn:"connectedAndroidTest"){
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
reports{
xml.enabled = false
html.enabled = true
csv.enabled = false
}
classDirectories = fileTree(
dir : "$buildDir/intermediates/classes/debug",
excludes : [
'**/*Test.class',
'**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*'
]
)
def coverageSourceDirs = ['src/main/java']
additionalSourceDirs = files(coverageSourceDirs)
sourceDirectories = files(coverageSourceDirs)
additionalClassDirs = files(coverageSourceDirs)
executionData = files("$buildDir/outputs/code-coverage/connected/coverage.ec")
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.1'
}
- 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
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 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
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
生成报告
配置完上面的步骤之后,打开Terminal,并输入命令gradlew jacocoTestReport,回车执行。
之后打开下面的地址,先看下测试结果
从上图,可以看到有些测试用例是没有跑通的,点击之后可以看详情信息
根据提示信息,修改代码,直到测试用例跑通之后,如下图:
然后打开下面的地址,如果测试用例没有全部跑通的话,就不会生成代码覆盖率报告。
我们去查看下,之前跑的测试用例的覆盖率情况
再点击进去的话,可以看到具体有哪些分支路径是没有覆盖到的。
将报告通过邮箱发送给相关人员
通过上面的步骤,我们已经可以看到了结果报告,但是,我们的主题是持续集成&自动化,所以,还没有全部完成,我们的主角依然是jenkins。所以,接下来要讲的是:通过jenkins项目配置,让程序自动生成报告,并将结果通过邮件发送给相关人员。
先后会创建“Publish JUnit test result report”、”Record JaCoCo coverage report “、“Publish Android Lint results”。
配置单元测试报告
这时候,报了个错误,说当前路径没有匹配到文件,没关系,因为我们还没有执行命令之前,一些文件夹还没有生成,所以可以先忽略。
配置代码覆盖率报告
主要的几个参数配置,“Path to class directories”配置的是编译后.class文件的路径地址,Android都是放在build路径下build\intermediates\classes;“Path to source directories”配置的是Java代码路径。
配置Android Lint报告
Android Lint是Android自带的一个功能,它可以检测一些不规范的写法,并提示。该功能gradle不用配置任何东西,只要执行build之后就会自动生成报告。
上图中不用填写入任何路径,默认的即可。
邮件配置及gradle执行命令的修改
首先,我们先修改下邮件的发送内容。
我们在上一节的基础上,只是新增加了以上3中报告的地址。
接着,还需要修改gradle 执行的命令。
项目的build.gradle修改下
去掉connectedAndroidTest的关联,因为我们已经独立使用命令执行connectedAndroidTest了,所以jenkins服务器在跑job的时候,请确保已经打开了Android模拟器,否则会出错。
查看邮件报告
配置完以上的步骤之后,将代码push到github上,等待jenkins触发构建或者我们手动执行构建都可以。
邮件里增加了配置里相应修改的内容。
注意:因为我的项目是一个lib项目,而在Android里lib项目生成的jar包是一个aar,所以这里的单元测试,我是写在lib项目里,然后构建产物,我也修改为获取aar包,修改如下:
总结
跟着上面的步骤来,我们就已完成了单元测试及代码覆盖率报告的自动化发邮件了,能及时发现错误,这在很大程度上保证了我们的代码是经测试的,是有效可靠的。下一篇,将讲如何使用findbugs插件进行查虫,包括gradle的配置和jenkins的配置,发送findbugs报告到邮箱,更进一步的提高代码质量。
Jenkins构建Android项目持续集成之单元测试及代码覆盖率的更多相关文章
- Jenkins构建Android项目持续集成之findbugs的使用
Findbugs简介 关于findbugs的介绍,可以自行百度下,这里贴下百度百科的介绍.findbugs是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题 ...
- 使用jenkins进行Android的持续集成
关于持续集成的定义和意义可以参考它的 百度百科 主要意义有以下几点: 减少风险 减少重复过程 任何时间.任何地点生成可部署的软件 增强项目的可见性 建立团队对开发产品的信心 持续集成的实施 持续集成的 ...
- jenkins部署github项目持续集成
一.先介绍正向代理和反向代理 正向代理 反向代理 二.安装反响代理得到固定域名 http://www.xiaomiqiu.cn/ 三.Jenkins与Github集成 配置前要求: 1.Jenkins ...
- Jenkins + testNg + maven 项目持续集成
搞了一整天,梳理下关键点: 1.项目的pom.xml要配置插件,同时指定testng.xml文件的位置.就被这个卡了好久 <properties> <maven-surefire-p ...
- Net 项目构建基于Jenkins + Github + Mono 的持续集成环境
Net 项目构建基于Jenkins + Github + Mono 的持续集成环境 阅读目录 1 安装 2 配置 3 测试 在Redhat enterprise 6.5 的服务器上,为在gutub 上 ...
- Jenkins +Maven+Tomcat+SVN +Apache项目持续集成构建
详解Jenkins +Maven+Tomcat+SVN +Apache项目持续集成 一:前言 1. Jenkins jenkins版本大全http://mirrors.jenkins-ci.org/ ...
- Framework项目持续集成(jenkins)及集合SonarQube
目录 Framework项目持续集成及集合SonarQube - 前言 CI/CD是什么 -- jenkins 什么是sonarqube?什么是CodeReview? 什么是sonarqube? 什么 ...
- Selenium Web 自动化 - 项目持续集成(进阶)
Selenium Web 自动化 - 项目持续集成(进阶) 2017-03-09 目录 1 背景及目标2 环境配置 2.1 SVN的安装及使用 2.2 新建Jenkins任务3 过程分析 1 背景 ...
- Selenium Web 自动化 - 项目持续集成
Selenium Web 自动化 - 项目持续集成 2017-02-13 目录 1环境准备 1.1 安装git 1.2 安装jenkins 1.3 安装jenkins插件 1.4 jekins ...
随机推荐
- 基于binlog来分析mysql的行记录修改情况(python脚本分析)
最近写完mysql flashback,突然发现还有有这种使用场景:有些情况下,可能会统计在某个时间段内,MySQL修改了多少数据量?发生了多少事务?主要是哪些表格发生变动?变动的数量是怎 ...
- iphone手机中对于html和css的一些特殊处理
1.iphone safari iso系统不兼容:hover的解决办法: 方法一: a:hover设置的样式在IOS系统的浏览器内显示不出来,看来是IOS系统的移动设备中,需要在按钮元素或者是body ...
- Spring+SpringMVc+Mybatis实现数据库查询
大家好,本篇博客小Y将会给大家带来一篇SSM框架实现数据查询的Demo,使用的数据库是Mysql,Server是TomCat.现在的SSM整合非常流行,因为springmvc的高效和mybatis的灵 ...
- Java中IO流的总结
有关Java中IO流总结图 流分类 按方向分 输入流 输出流 按单位分 字节流 字符流 按功能分 节点流 处理流(过滤流) 其他 所有的流继承与这四类流:InputSteam.OutputStream ...
- 用java来实现验证码功能。
昨天在网上看到了一篇关于验证码的文章,很不错,但是有些不尽人意的地方,比如没有考虑到前端传过来的验证码如果是小写的话,那么做验证的时候就会出现错误, 因为java是严格区分大小写的,还有就是验证码会重 ...
- 设计模式的征途—8.桥接(Bridge)模式
在现实生活中,我们常常会用到两种或多种类型的笔,比如毛笔和蜡笔.假设我们需要大.中.小三种类型的画笔来绘制12中不同的颜色,如果我们使用蜡笔,需要准备3*12=36支.但如果使用毛笔的话,只需要提供3 ...
- python之路第一篇
一.python环境的搭建 1.window下环境的搭建 (1).在 https://www.python.org/downloads/ 下载自己系统所需要的python版本 (2).安装python ...
- 掌握Chrome Developer Tools:下一阶段前端开发技术
Tips 原文作者:Ben Edelstein 原文地址:Mastering Chrome Developer Tools: Next Level Front-End Development Tech ...
- 机器学习:保序回归(IsotonicRegression):一种可以使资源利用率最大化的算法
1.数学定义 保序回归是回归算法的一种,基本思想是:给定一个有限的实数集合,训练一个模型来最小化下列方程: 并且满足下列约束条件: 2.算法过程说明 从该序列的首元素往后观察,一旦出现乱序现象停止该轮 ...
- maven插件打包可执行jar
pom文件加 <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</grou ...