一、概述:
使用AndroidTest,我们可以获取到Android运行的环境,并且通过在测试文件中实例化我们需要测试的类,然后自己模拟一些参数去调用实例中的方法,来达到测试代码的目的。一个AndroidTest文件,就相当于一个运行进程一样,可以在真机上运行,并且可以把测试跑后的结果统计出来,作为研发自测重要的一个根据。
二、创建测试单元
我们可以针对我们代码中那些很关键的控制性类创建一个测试单元,这样创建的测试单元就可以包含很多内容。创建的方式也很简单,在需要创建的类边上进入提示,如下:
点击Create Test
在这个界面可以勾选需要测试的方法,这些都是public方法,否侧是测试不了的。
勾选完成点击OK,就会在androidTest的相同目录层级下创建一个对应的测试类。类似这样:
以上的每个方法都会被测试框架执行到,可以整个测试单元一起运行测试,也可以测试单个方法。
三、实现测试单元
我们实现测试单元的主要思想,就是要把我们项目中的代码尽量多地执行到,主要手段就是实例化我们需要测试的类,并且调用实例对象里的方法,来执行代码。如下:
这里就创建了实例对象,而且还调用了初始化的方法,这样我们就可以测试到我们这个类的构造方法以及对应的初始化的方法了。
如果需要传入参数,那么我们就自己创建一个或者一组参数,去调用方法,如下:
这里我是模拟回调监听得到数据后处理的方法,是一组参数,可以覆盖更多的switch分支。
四、运行调试
运行测试单元之后,AS控制台就会显示运行测试的结果,如下:
显示7个方法都通过测试运行,如果测试有问题,这里也会打印提示,逐个修改即可。
五、输出覆盖率报告
这一步骤相对比较麻烦,可以分为以下几个小步骤实现:
1.新建一个coverage.gradle文件,并且把这个文件放在项目的根目录下
coverage.gradle的内容如下:
apply plugin: 'jacoco'
def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*'
, 'android/**/*.*',
'**/*_Factory.**/**'
, '**/Dagger**.**',
'**/*_Factory.InstanceHolder/**'
, '**/**Module_Provides**.InstanceHolder/**',
'**/**Module_Provides**.**/**',
'**/**_MembersInjector**.class',
'**/**Bean.class',
'**/**DataPack.class',
'**/**Pack.class',
'**/di/**',
'**/**Fragment**.*',
'**/**Activity**.*',
'**/**ViewHolder**.*',
'**/**Adapter**.*',
'**/**View.*',
'**/**Layout**.*',
'**/**LayoutManager**.*',
'**/**Widget**.*',
'**/**Dialog**.*',
'**/**UriMedia.*',
'**/**_Impl**.*',
'**/views/**',
'**/widgets/**',
]
task jacocoTestReport(type: JacocoReport, dependsOn: ['connectedDebugAndroidTest', 'createDebugCoverageReport','testDebugUnitTest']) {
reports {
xml.enabled = true
html.enabled = true
csv.enabled = true
}
def debugTree = fileTree(dir: "${buildDir}/intermediates/javac/debug", excludes: fileFilter)
def mainSrc = "${project.projectDir}/src/main/java"
sourceDirectories.from = files([mainSrc])
classDirectories.from = files([debugTree])
executionData.from = fileTree(dir: "$buildDir", includes: [
"jacoco/testPlayDebugUnitTest.exec",
"outputs/code_coverage/debugAndroidTest/connected/*coverage.ec"
])
}
/**
* 直接生成报告,适用于单独跑完测试后,基于现有数据生成测试报告
* 如:
* ./gradlew presentation:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.lixiang.neteasemusic.features.player.vm.FullScreenLyricViewModelTest#dispatchLyricFullScreenStateLock && ./gradlew presentation:jacocoTestReportDirect
*/
task jacocoTestReportDirect(type: JacocoReport) {
reports {
xml.enabled = true
html.enabled = true
csv.enabled = true
}
def debugTree = fileTree(dir: "${buildDir}/intermediates/javac/debug", excludes: fileFilter)
def mainSrc = "${project.projectDir}/src/main/java"
sourceDirectories.from = files([mainSrc])
classDirectories.from = files([debugTree])
executionData.from = fileTree(dir: "$buildDir", includes: [
"jacoco/testPlayDebugUnitTest.exec",
"outputs/code_coverage/debugAndroidTest/connected/*coverage.ec"
])
}
2.在总项目的build.gradle中加入相关配置,如下:
3.在测试的module目录中的build.gradle文件中,引用测试相关的库文件,如下:
当然了,我们还要把覆盖率的开关打开:
4.最后最关键的一步,就是通过命令生成覆盖报告文件。在AS控制台中,默认就是在本项目的文件夹下,输入如下命令:
./gradlew app:jacocoTestReport
这里的app可以换成你自己想要测试的module的名字。
运行完成之后,就会在build目录下生成一个reports文件夹,然后看jacoco -> jacocoTestReport,这里面就可以看到相关的测试报告了。选择html的测试报告打开,如下:
这样就清清楚楚了,点进每一项里面,还可以查看更加详细的覆盖情况,很是直观便捷!