在软件开发中一直在推崇TDD(测试驱动开发),可是一直不能被有效的执行或者并非真正的测试驱动开发(先开发后写单元测试),由于咱们懒!而Android开发又是大多应用层面的开发,不少都是和视图层紧密相连的,业务逻辑和view相绑定,这致使编写单元测试有至关大的困难,所以就我项目而言,只针对工具类、服务端API编写单元测试。关于android Studio如何编写单元测试并运行,能够看以前写的一篇文章Android Studio 单元测试html
编写好单元测试后,咱们须要知道,测试用例是否覆盖了代码的全部分支状况,这样才能保证代码的可靠性、正确性。java
若是使用Android Studio建立项目的话,那么默认的会在androidTest包下生成一个ApplicationTest类,在这里面能够写测试用例。android
上图写的是一个SharedPreferences Util工具类的测试用例。
若是你的测试用例不想写在这个包下,想自定义,也能够在项目的build.gradle写以下的配置git
android {
sourceSets { androidTest{ java.srcDirs = ['src/com/helen/andbase/tests'] } }
Jacoco是一个开源的覆盖率工具。这里讲下gradle如何配置。
首先要在项目的build.gradle引入插件,语句以下:github
apply plugin: 'jacoco'
而后注明使用的版本号bash
jacoco{
version "0.7.4.201502262128" }
接着,申明一个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") }
最后,打开testCoverageEnabled,须要注意的是,打开该属性的话,在断点调试的时候会致使方法参数值丢失(看不到),因此在调试的时候要记得把它关掉。app
buildTypes {
debug{ testCoverageEnabled true } }
完整的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' }
配置完上面的步骤以后,打开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自带的一个功能,它能够检测一些不规范的写法,并提示。该功能gradle不用配置任何东西,只要执行build以后就会自动生成报告。
上图中不用填写入任何路径,默认的便可。
首先,咱们先修改下邮件的发送内容。
咱们在上一节的基础上,只是新增长了以上3中报告的地址。
接着,还须要修改gradle 执行的命令。
项目的build.gradle修改下
去掉connectedAndroidTest的关联,由于咱们已经独立使用命令执行connectedAndroidTest了,因此jenkins服务器在跑job的时候,请确保已经打开了Android模拟器,不然会出错。
配置完以上的步骤以后,将代码push到github上,等待jenkins触发构建或者咱们手动执行构建均可以。
邮件里增长了配置里相应修改的内容。
注意:由于个人项目是一个lib项目,而在Android里lib项目生成的jar包是一个aar,因此这里的单元测试,我是写在lib项目里,而后构建产物,我也修改成获取aar包,修改以下:
跟着上面的步骤来,咱们就已完成了单元测试及代码覆盖率报告的自动化发邮件了,能及时发现错误,这在很大程度上保证了咱们的代码是经测试的,是有效可靠的。下一篇,将讲如何使用findbugs插件进行查虫,包括gradle的配置和jenkins的配置,发送findbugs报告到邮箱,更进一步的提升代码质量。