一、工具简介
JUnit Java 单元测试框架,是Android单元测试的基础
Robolectric 直接运行在JVM上,提供Android代码的运行环境(不需要虚拟机或Android设备)
JaCoCo 单元测试覆盖率工具
二、 配置
1.JUnit + Robolectric配置
testImplementation 'junit:junit:4.12'
testImplementation 'org.robolectric:robolectric:4.0-alpha-2’
2.JaCoCo配置
android {
buildTypes {
debug {
testCoverageEnabled = true
}
}
}
apply plugin ‘jacoco'
jacoco {
toolVersion = "0.7.1.201405082137" //版本号可用最新
}
def coverageSourceDirs = [
'../deckard-master/src/main/java' // deckard-master需要修改为你的module名称
]
task jacocoTestReport(type:JacocoReport, dependsOn: "testDebugUnitTest") {
group = "Reporting"
description = "Generate Jacoco coverage reports"
// 下面dir deckard-master需要修改为你的module名称
classDirectories = fileTree(
dir: '../deckard-master/build/intermediates/classes/debug',
excludes: ['**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/BuildConfig.*',
'**/Manifest*.*'] // 去掉不进行检查的文件
)
additionalSourceDirs = files(coverageSourceDirs)
sourceDirectories = files(coverageSourceDirs)
// 下面dir deckard-master需要修改为你的module名称
executionData = files('../deckard-master/build/jacoco/testDebugUnitTest.exec')
reports {
xml.enabled = true
html.enabled = true
}
}
三、实例
1.单元测试用例
@RunWith(RobolectricTestRunner.class)
public class DeckardActivityTest {
@Test
public void testSomething() throws Exception {
ShadowApplication shadowApplication = Shadows.shadowOf(RuntimeEnvironment.application);
assertNotNull(shadowApplication);
String packageName = shadowApplication.getApplicationContext().getPackageName();
assertEquals(packageName, "com.example");
PackageInfo info = shadowApplication.getApplicationContext().getPackageManager()
.getPackageInfo(packageName, 0);
assertNotNull(info);
assertEquals(info.versionCode, 2);
DeckardActivity mainActivity = Robolectric.setupActivity(DeckardActivity.class);
assertTrue(mainActivity != null);
TextView textView = mainActivity.findViewById(R.id.text);
assertNotNull(textView);
Toast.makeText(shadowApplication.getApplicationContext(), textView.getText().toString(), Toast.LENGTH_SHORT).show();
assertEquals(ShadowToast.getTextOfLatestToast(), "Hello Espresso!");
}
@Test
public void testOtherSomething() throws Exception {
ShadowApplication shadowApplication = Shadows.shadowOf(RuntimeEnvironment.application);
assertNotNull(shadowApplication);
String packageName = shadowApplication.getApplicationContext().getPackageName();
assertEquals(packageName, "com.example");
}
}
2.执行用例
./gradleview jacocoTestReport
3.执行结果:失败,不会生成覆盖率报告
MacBook-Pro:~/Downloads/deckard-master$ gradle jacocoTestReport
> Task :testDebugUnitTest
objc[3044]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/bin/java (0x105a234c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x105aa74e0). One of the two will be used. Which one is undefined.
com.example.activity.DeckardActivityTest > testSomething FAILED
org.junit.ComparisonFailure at DeckardActivityTest.java:44
2 tests completed, 1 failed
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':testDebugUnitTest'.
> There were failing tests. See the report at: file:///Users/Jason/Downloads/deckard-master/build/reports/tests/testDebugUnitTest/index.html
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
* Get more help at https://help.gradle.org
BUILD FAILED in 15s
22 actionable tasks: 2 executed, 20 up-to-date
MacBook-Pro:~/Downloads/deckard-master$
其中 file:///Users/Jason/Downloads/deckard-master/build/reports/tests/testDebugUnitTest/index.html
就是测试详情,如下图所示
4.执行结果:成功,生成覆盖率报告
Jason@YuSongdeMacBook-Pro:~/Downloads/deckard-master$ gradle jacocoTestReport
> Task :testDebugUnitTest
objc[3100]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/bin/java (0x10c18a4c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10d1b54e0). One of the two will be used. Which one is undefined.
BUILD SUCCESSFUL in 16s
23 actionable tasks: 16 executed, 7 up-to-date
Jason@YuSongdeMacBook-Pro:~/Downloads/deckard-master$
成功时才会生成覆盖率报告,路径为:build/reports/jacoco/jacocoTestReport/html/index.html, 如图所示:
参考
1.Robolectric 用法及API文档 :http://robolectric.org/
2.美团Android单元测试研究与实践: https://tech.meituan.com/Android_unit_test.html
3.与 Jenkins CI 的结合:https://www.jianshu.com/p/b8a7dfefba96