php 手工测试 覆盖率,手工测试如何获得代码覆盖率?大佬解释得太详细了!

本文详细介绍了使用JaCoCo在Android项目中实现代码覆盖率测试的过程,包括配置build.gradle文件、处理Ec文件、解决启动应用闪退等问题。通过调整测试入口和处理主题兼容性,确保了测试数据的准确记录。文章总结了多种场景下的解决方案,强调了成功记录数据的重要性。
摘要由CSDN通过智能技术生成

jacoco { //插件版本设置toolVersion = "0.8.5"}android {compileSdkVersion 30buildToolsVersion "30.0.1"

defaultConfig {applicationId "com.morn.aaa"minSdkVersion 23targetSdkVersion 30versionCode 1versionName "1.0"

testInstrumentationRunnerArguments clearPackageData: 'true'//instrument设置}

buildTypes {debug {testCoverageEnabled = true//JaCoCo功能启动}}}//ec文件解析函数def coverageSourceDirs = ['../app/src/main/java']task jacocoTestReport( type: JacocoReport){group= "Reporting"deion = "Generate Jacoco coverage reports after running tests."reports {xml.enabled = truehtml.enabled = truecsv.enable = true}classDirectories. from= fileTree(dir: './build/intermediates/javac/debug',excludes: [ '**/R*.class','**/*$InjectAdapter.class','**/*$ModuleAdapter.class','**/*$ViewInjector*.class'])sourceDirectories. from= files(coverageSourceDirs)executionData. from= files( "$buildDir/outputs/code-coverage/connected/coverage.ec")

doFirst {newFile( "$buildDir/intermediates/javac/").eachFileRecurse { file ->if(file.name.contains( '$$')) {file.renameTo(file.path.replace( '$$', '$'))}}}}

dependencies {implementation fileTree( dir: "libs", include: [ "*.jar"])}

这是app/build.gradle的一个例子,关键部分我都加了注释。得到ec文件之后,需要将Android设备下的ec文件,放置到$buildDir/outputs/code-coverage/connected/coverage.ec然后运行jacocoTestReport这个task,运行成功后会在$buildDir/reports/jacoco目录下生成根据eoverage.ec转义的html等文件,html目录下的index.html可以可视化展示代码覆盖率数据。

462351f674250db7a1333b7d70f2964a.png

一些bug

jacoco.exec

W/System.err: java.io.FileNotFoundException: /jacoco.exec (Read-only file system)

这应该是JaCoCo库包的一些问题,由于Android平台的特殊性导致的,JaCoCo的开发者也没提出明确的解决方案。但是,不影响我们这里要求的功能。

切页面闪退

网上一些例子中会出现切换Activity,应用闪退的问题。我一开始也是照着这个例子来的,也出现了这个问题,分析是代码思路有问题,一是只有由Instrument开启的Activity才设置了listener,二是,切换Activity会调用finish方法,直接就结束了应用。反正我一通删删删之后,可以正常运行了。

Instrument命令无反应

可能是targetPackage配置的问题,有些时候AndroidManifest.xml里设置的package不一定是实际安装时应用的package名。

< manifestxmlns:android= "http://schemas.android.com/apk/res/android"package= "org.glucosio.android">······< instrumentationandroid:name= "test.JacocoInstrumentation"android:handleProfiling= "true"android:label= "CoverageInstrumentation"android:targetPackage= "org.glucosio.android.daily"/>//实际安装的包名变化了 manifest>

比如这个例子,在构建文件build.gradle里面对debug和release版本的包名做了修改,所以,实际安装的时候,应用对应的包名并不是AndroidManifest.xml里配置的那样。

解决方案就是,编译完,知道真实的包名后再配置。O(∩_∩)O还有,在AS里面,targetPackage属性无论配置正确与否都会飘红报错,但是,这并不影响编译运行。

启动应用闪退

在设置了假入口类,并通过Instrument启动的时候,可能会遇到应用启动闪退的情况,这是因为很多应用会改写Theme,然后Fake入口类继承的真实入口类需要对应的Theme配置,这里出现了配置,或者资源不兼容的情况,造成了闪退。

< activityandroid:name= ".activity.SplashActivity"android:label= "@string/app_name"android:theme= "@style/SplashTheme">< intent-filter>< actionandroid:name= "android.intent.action.MAIN"/>< categoryandroid:name= "android.intent.category.LAUNCHER"/> intent-filter>< meta-dataandroid:name= "android.app.shortcuts"android:resource= "@xml/shortcuts"/> activity>

< activityandroid:name= "test.InstrumentedActivity"android:label= "@string/app_name"android:theme= "@style/SplashTheme">< meta-dataandroid:name= "android.app.shortcuts"android:resource= "@xml/shortcuts"/> activity>

上面例子里的InstrumentedActivity就是继承了真实入口类SplashActivity的Fake入口类。

解决方案,继承一切真实入口类可以被继承的属性,比如theme什么的,这样在FakeActivity实例化加载资源的时候,可以避免出现资源申请失败的问题,防止出现应用启动闪退的现象。

进阶

本方法的主要功能就是generateCoverageReport,所以,何时调用,是最主要的问题!最理想的状态,在测试退出的时候调用,写入一次,节省时间,性能也高。但是,大多数场景下,这种情况是行不通的。以下我整理几个场景,以及解决方案,提供参考:

入口类是一次性的,比如加载页面,广告页面等等;

入口类显性调用,指定了Activity跳转的目标类名,无法重回我们重写的Fake入口类;

以下可以提供一些解决方案:

Application的onTerminate方法重写,在这里打桩调用记录函数,但是Application的生命周期监听在不同设备上有区别,貌似只在模拟器上有用。

BaseActivity的onDestroy方法重写,一般大型的Android项目都会有一个自定义的顶级Activity,重写销毁监听函数,在这里打桩,这样每次Activity退出都会记录一次数据,当然,这也是在其子类重写但没有覆盖父类这个操作的情况下;

MainActivity的onDestroy方法重写,这种方法是最保险的方法,这里的MainActivity指代应用首页对应的Activity。虽然,很多时候这个MainActivity不一定是入口类,但是只要在测试的时候能够最终回到MainActivity所在的页面,然后通过Android的回退键退出,调用onDestrooy记录数据。

总结

通过JaCoCo记录覆盖率的核心是调用记录函数,重点是保证记录函数能被成功调用。所以,Instrument也好,Service也好,直接写在原来的Activity里也好,目的都是成功记录数据。没有通用的万能方法,还是得因地制宜。在复杂的项目环境下,还是需要对原生代码进行适当的打桩修改的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值