当前位置: 首页 > news >正文

做阿里巴巴的网站的费用三亚百度推广公司电话

做阿里巴巴的网站的费用,三亚百度推广公司电话,淄博 网站建设,做汉字词卡的网站背景 主要是记录下Android项目使用jacoco生成代码覆盖率的实战流程,目前已完成全量覆盖方案,仅使用jacoco就能实现; 由于我们的Android端是使用Java和kotlin语言,目前增量的方案code-diff仅针对Java代码,卡在kotlin文件的分析&am…

背景

主要是记录下Android项目使用jacoco生成代码覆盖率的实战流程,目前已完成全量覆盖方案,仅使用jacoco就能实现;
由于我们的Android端是使用Java和kotlin语言,目前增量的方案code-diff仅针对Java代码,卡在kotlin文件的分析,仍在思考中。

Android由于是本地安装包,只能使用offline模式:

offline模式就是在测试之前先对文件进行插桩,生成插过桩的class或jar包,测试插过桩的class和jar包,生成覆盖率信息到文件,最后统一处理,生成报告。

在测试前先对文件进行插桩,然后生成插过桩的class或jar包,测试插过桩的class和jar包后,会生成动态覆盖信息到文件,最后统一对覆盖信息进行处理,并生成报告。

使用场景

其实主要是基于两个痛点:

1、新功能测试和回归测试在手工测试的情况下,即便用例写的再怎么详细,也经常会有漏测的发生,这里一方面是因为现在大量互联网公司采用外包资源来做业务测试,而外包的工作质量无法有效评估,可能存在漏执行的情况,另外一方面是本身测试用例设计的不够完善导致没有覆盖到一些关键路径的代码分支,因此亟需一种可以度量手工测试完成后对代码覆盖情况的手段或者工具;

2、研发代码变更的影响范围难以精准评估,比如研发提交一个MR,这个MR到底影响了多少用例,在没有精准测试能力的情况下是很难给出的,而做精准测试,最重要的一环就是代码用例的关系库维护,如何生成代码跟用例的关系,就需要用到代码覆盖率的采集和分析能力了;
引用简单两步实现 Jacoco+Android 代码覆盖率的接入!(最新最全版)

时机:
1.提测时-明确整个版本迭代的改动范围,测试范围,全量代码diff;
2.测试中-提交bug修复版本,明确问题,使用增量代码diff;
3.预发布-关注关键点,确保发布代码与测试代码一致,全量代码diff;

覆盖率对测试提升:
1.能了解确认需求的实现逻辑,对技术细节查漏补缺;
2.评估影响范围;
3.通过代码补充测试范围,优化测试用例;
4.加深系统实现的理解;
5.提前发现错误

项目环境

1.gradle插件版本
ANDROID_GRADLE_PLUGIN = "4.2.0"2.gradle依赖版本
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip3.android sdk版本
BUILD_TOOLS_VERSION = "28.0.3"
COMPILE_SDK = 31
TARGET_SDK = 31
MIN_SDK = 21

代码介入

1.在app模块下新建一个 jacoco.gradle

apply plugin: 'jacoco'
jacoco {toolVersion = "0.8.2"
}android {//在app引入的时候指定对应的变体 会将内容传递引用的工程,主要用于多模块使用defaultPublishConfig "debug"buildTypes {debug {/**打开覆盖率统计开关**/testCoverageEnabled = true}}
}
//源代码路径,你有多少个module,你就在这写多少个路径
//我这里是多模块的,需要将主要代码的模块写上
def coverageSourceDirs = ['../lib.xx/src/main/java','../lib.xx/src/main/java','../lib.xx/src/main/java','../lib.xx/src/main/java',......'/src/main/java','/src/mvp/java'
]//class文件路径,就是上面提到的class路径,看你的工程class生成路径是什么,替换一下就行
def coverageClassDirs = ['/lib.xx/build/intermediates/javac/debug/classes','/lib.xx/build/intermediates/javac/debug/classes','/lib.xx/build/intermediates/javac/debug/classes','/lib.xx/build/intermediates/javac/debug/classes','/app/build/intermediates/javac/debug/classes'......
]
//kotlin的classes文件
def kotlinClassDirs = ['/lib.xx/build/tmp/kotlin-classes/debug/','/lib.xx/build/tmp/kotlin-classes/debug/','/lib.xx/build/tmp/kotlin-classes/debug/','/lib.xx/build/tmp/kotlin-classes/debug/','/app/build/tmp/kotlin-classes/debug/'......
]//这个就是具体解析ec文件的任务,会根据我们指定的class路径、源码路径、ec路径进行解析输出
task jacocoTestReport(type: JacocoReport) {group = "Reporting"description = "Generate Jacoco coverage reports after running tests."reports {xml.enabled(true)html.enabled(true)}//设置class文件的路径classDirectories.setFrom(files(coverageClassDirs.collect{fileTree(dir: "$rootDir"+it,excludes: ['**/R*.class','**/*$InjectAdapter.class','**/*$ModuleAdapter.class','**/*$ViewInjector*.class'])}))classDirectories.setFrom(files(kotlinClassDirs.collect{fileTree(dir: "$rootDir"+it,excludes: ['**/R*.class','**/*$InjectAdapter.class','**/*$ModuleAdapter.class','**/*$ViewInjector*.class'])}))//设置源码文件的路径sourceDirectories.setFrom(files(coverageSourceDirs))
//设置ec文件executionData.setFrom(files("$buildDir/outputs/code_coverage/debugAndroidTest/connected/coverage.ec"))doFirst {coverageClassDirs.each { path ->println("$rootDir" + path)new File("$rootDir" + path).eachFileRecurse { file ->if (file.name.contains('$$')) {file.renameTo(file.path.replace('$$', '$'))}}}}
}

2.在app模块下的build.gradle.kts引用jacoco.gradle,并在buildtype为debug下开启覆盖率的开关

apply(from = "jacoco.gradle")//引入jacoco
// 开发版本,可打开开发者模式getByName("debug") {isMinifyEnabled = false//引入jacocoisTestCoverageEnabled = truezipAlignEnabled(false)

3.定义采集覆盖率coverage.ec的方式,网上的方式都是通过监听主activity Destroy后收集,这里可以自己定义适合的方式,比如在项目新增按钮点击采集。参考网上的代码可以,直接用:

在app的代码新建jacoco目录
添加一下代码
在这里插入图片描述

FinishListener

package xx.app.jacoco;public interface FinishListener {void onActivityFinished();void dumpIntermediateCoverage(String filePath);
}

InstrumentedActivity

package xx.app.jacoco;import xx.Activity;public class InstrumentedActivity extends Activity {public FinishListener finishListener;public void setFinishListener(FinishListener finishListener) {this.finishListener = finishListener;}@Overridepublic void onDestroy() {if (this.finishListener != null) {finishListener.onActivityFinished();}super.onDestroy();}
}

JacocoInstrumentation

public class JacocoInstrumentation extends Instrumentation implements FinishListener {public static String TAG = "JacocoInstrumentation:";@SuppressLint("SdCardPath")private static String DEFAULT_COVERAGE_FILE_PATH = "/mnt/sdcard/coverage.ec";private final Bundle mResults = new Bundle();private Intent mIntent;private static final boolean LOGD = true;private boolean mCoverage = true;private String mCoverageFilePath;public JacocoInstrumentation() {}@Overridepublic void onCreate(Bundle arguments) {Log.e(TAG, "onCreate(" + arguments + ")");super.onCreate(arguments);DEFAULT_COVERAGE_FILE_PATH = getContext().getFilesDir().getPath() + "/coverage.ec";File file = new File(DEFAULT_COVERAGE_FILE_PATH);if (file.isFile() && file.exists()) {if (file.delete()) {Log.e(TAG, "file del successs");} else {Log.e(TAG, "file del fail !");}}if (!file.exists()) {try {file.createNewFile();} catch (IOException e) {Log.e(TAG, "异常 : " + e);e.printStackTrace();}}if (arguments != null) {Log.e(TAG, "arguments不为空 : " + arguments);mCoverageFilePath = arguments.getString("coverageFile");Log.e(TAG, "mCoverageFilePath = " + mCoverageFilePath);}mIntent = new Intent(getTargetContext(), InstrumentedActivity.class);mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);start();}@Overridepublic void onStart() {Log.e(TAG, "onStart def");if (LOGD) {Log.e(TAG, "onStart()");}super.onStart();Looper.prepare();InstrumentedActivity activity = (InstrumentedActivity) startActivitySync(mIntent);activity.setFinishListener(this);}private boolean getBooleanArgument(Bundle arguments, String tag) {String tagString = arguments.getString(tag);return tagString != null && Boolean.parseBoolean(tagString);}private void generateCoverageReport() {OutputStream out = null;try {out = new FileOutputStream(getCoverageFilePath(), false);Object agent = Class.forName("org.jacoco.agent.rt.RT").getMethod("getAgent").invoke(null);out.write((byte[]) agent.getClass().getMethod("getExecutionData", boolean.class).invoke(agent, false));} catch (Exception e) {Log.e(TAG, e.toString());e.printStackTrace();} finally {if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}}}private String getCoverageFilePath() {if (mCoverageFilePath == null) {return DEFAULT_COVERAGE_FILE_PATH;} else {return mCoverageFilePath;}}private boolean setCoverageFilePath(String filePath) {if (filePath != null && filePath.length() > 0) {mCoverageFilePath = filePath;return true;}return false;}private void reportEmmaError(Exception e) {reportEmmaError("", e);}private void reportEmmaError(String hint, Exception e) {String msg = "Failed to generate emma coverage. " + hint;Log.e(TAG, msg);mResults.putString(Instrumentation.REPORT_KEY_STREAMRESULT, "\nError: "+ msg);}@Overridepublic void onActivityFinished() {if (LOGD) {Log.e(TAG, "onActivityFinished()");}if (mCoverage) {Log.e(TAG, "onActivityFinished mCoverage true");generateCoverageReport();}finish(Activity.RESULT_OK, mResults);}@Overridepublic void dumpIntermediateCoverage(String filePath) {// TODO Auto-generated method stubif (LOGD) {Log.e(TAG, "Intermidate Dump Called with file name :" + filePath);}if (mCoverage) {if (!setCoverageFilePath(filePath)) {if (LOGD) {Log.e(TAG, "Unable to set the given file path:" + filePath + " as dump target.");}}generateCoverageReport();setCoverageFilePath(DEFAULT_COVERAGE_FILE_PATH);}}
}

配置AndroidManifest.xml

<!--引入jacoco--><activity android:name=".jacoco.InstrumentedActivity"android:label="InstrumentationActivity"/>
<!--引入jacoco--><instrumentationandroid:name=".jacoco.JacocoInstrumentation"android:handleProfiling="true"android:label="CoverageInstrumentation"android:targetPackage="包名" />

统计子module的覆盖率

因为很多Android项目肯定不只要app module,有很多子module提供使用,需要一起统计覆盖率
目前的做法是在jacoco.gradle 加上参数 defaultPublishConfig “debug”

android {//在app 引入的时候指定对应的变体 会将内容传递引用的工程,主要用于多模块使用defaultPublishConfig "debug"buildTypes {debug {/**打开覆盖率统计开关**/testCoverageEnabled = true}}
}

然后让子module去引用,这就需要修改子module的build.gradle,一行代码完成

//在子模块引入jacoco
apply(from = "../app/jacoco.gradle")

实战使用

1.通过命令行打debug安装包
installDebug 或者 gradlew app都行

2.通过instrument 启动app
安装完后先打开app再退出一下,不然启动不了

adb shell pm list instrumentation
//会看到以下信息
instrumentation:xx.app/.jacoco.JacocoInstrumentation (target=xx.app)
//然后复制启动
adb shell am instrument xx.app/.jacoco.JacocoInstrumentation

3.执行测试

4.完成测试后,在主页面退出app

5.通过Android stdio的device file explorer复制出coverage.ec
路径 /data/data/xx.app/files/coverage.ec

6.将coverage.ec复制到项目文件\app\build\outputs\code_coverage\debugAndroidTest\connected下,如没有的话新建

7.用命令jacocoTestReport生成报告,报名路径如下:
\app\build\reports\jacoco\jacocoTestReport\html
在这里插入图片描述

增量代码覆盖率

使用code-diff 和 jacoco二开

用code-diff获取两个commit之间的代码差异,然后生成json文件,使用jacoco二开的jar包通过
–diffCodeFiles 传入差异代码json文件,然后只生成差异代码文件的覆盖报告
在这里插入图片描述

在这里插入图片描述
总结:KT文件需要改造code-diff才能用,目前只能用于java,后续看看怎么修改。

引用下该作者的话,总结得很好,学习学习:

代码覆盖率100% 不代表没有bug。代码没有覆盖100% 一定有bug;
但是有可能你覆盖到80% 很轻松,往后增加5% 都费很大劲。那么我们可以去没有覆盖到的进行分析。不一定要做到代码100%全覆盖,尤其在功能测试阶段,代码100% 覆盖,会给大家增加很多的工作量,很有可能为了1%的覆盖率而耽误整体测试,得不偿失。
覆盖率是为了提升我们测试用例的覆盖度,检验我们测试用例设计的全面性,它有两面性,合理引入覆盖率,合理选择一定的阈值。

https://cloud.tencent.com.cn/developer/article/1801772


文章转载自:
http://fragmental.dtrz.cn
http://qic.dtrz.cn
http://swordproof.dtrz.cn
http://swagger.dtrz.cn
http://shuba.dtrz.cn
http://berat.dtrz.cn
http://crispin.dtrz.cn
http://tariff.dtrz.cn
http://incogitability.dtrz.cn
http://ecosphere.dtrz.cn
http://foliole.dtrz.cn
http://yenta.dtrz.cn
http://hecla.dtrz.cn
http://hackle.dtrz.cn
http://attar.dtrz.cn
http://quincunx.dtrz.cn
http://ark.dtrz.cn
http://platinoid.dtrz.cn
http://newsroom.dtrz.cn
http://jangler.dtrz.cn
http://nacho.dtrz.cn
http://gelid.dtrz.cn
http://intubate.dtrz.cn
http://unhinge.dtrz.cn
http://artware.dtrz.cn
http://tealess.dtrz.cn
http://wheatgrass.dtrz.cn
http://tempestuously.dtrz.cn
http://centrifugal.dtrz.cn
http://lamb.dtrz.cn
http://precondemn.dtrz.cn
http://perfectly.dtrz.cn
http://permeant.dtrz.cn
http://hesperia.dtrz.cn
http://waterweed.dtrz.cn
http://snell.dtrz.cn
http://opern.dtrz.cn
http://sinople.dtrz.cn
http://allergic.dtrz.cn
http://learning.dtrz.cn
http://overtype.dtrz.cn
http://thyroglobulin.dtrz.cn
http://segar.dtrz.cn
http://christian.dtrz.cn
http://huh.dtrz.cn
http://inexplosive.dtrz.cn
http://tout.dtrz.cn
http://anoesis.dtrz.cn
http://eustonian.dtrz.cn
http://grimace.dtrz.cn
http://septennia.dtrz.cn
http://colourbearer.dtrz.cn
http://defaecate.dtrz.cn
http://lazy.dtrz.cn
http://ontogenesis.dtrz.cn
http://underpaid.dtrz.cn
http://dindle.dtrz.cn
http://physiotherapeutic.dtrz.cn
http://agleam.dtrz.cn
http://fulvous.dtrz.cn
http://setdown.dtrz.cn
http://kiev.dtrz.cn
http://springtail.dtrz.cn
http://catnap.dtrz.cn
http://lava.dtrz.cn
http://banquette.dtrz.cn
http://mulhouse.dtrz.cn
http://heshvan.dtrz.cn
http://at.dtrz.cn
http://sentimentalist.dtrz.cn
http://biennial.dtrz.cn
http://acini.dtrz.cn
http://scriptural.dtrz.cn
http://noncountry.dtrz.cn
http://leninakan.dtrz.cn
http://pen.dtrz.cn
http://tackling.dtrz.cn
http://pulverable.dtrz.cn
http://mellophone.dtrz.cn
http://unfeed.dtrz.cn
http://pressor.dtrz.cn
http://undock.dtrz.cn
http://hydrophytic.dtrz.cn
http://nutation.dtrz.cn
http://thunderpeal.dtrz.cn
http://harbour.dtrz.cn
http://standpoint.dtrz.cn
http://vividly.dtrz.cn
http://salify.dtrz.cn
http://jena.dtrz.cn
http://gondwanaland.dtrz.cn
http://unlet.dtrz.cn
http://knowability.dtrz.cn
http://undiminishable.dtrz.cn
http://eng.dtrz.cn
http://archesporial.dtrz.cn
http://constative.dtrz.cn
http://dogly.dtrz.cn
http://secretive.dtrz.cn
http://laevorotation.dtrz.cn
http://www.dt0577.cn/news/106976.html

相关文章:

  • 做网站换域名引流推广软件
  • 锟鹏建设招聘网站今日重大新闻头条十条
  • 建站平台代理免费推广网站地址大全
  • 网站开发后端所需要的语言短视频seo排名加盟
  • 真人棋牌网站怎么做seo厂商
  • 自己做的网站如何放到微信360推广登陆
  • 网站集群建设方案产品网络营销
  • 做网站一年了 做个小总结开封网络推广哪家好
  • 开源门户网站源码百度seo优化教程
  • 常州微信网站制作网页设计与制作书籍
  • 自己做的网站怎么发布津seo快速排名
  • 网站建设实验报告总结两千字网络营销推广渠道有哪些
  • 石河子做网站公司软文代写发布
  • WordPress超级链接不跳转木卢seo教程
  • 如何将网站排名做高广州品牌营销策划公司排名
  • 海南做网站百度推广电话客服24小时
  • 杨浦手机网站建设企业培训课程设置
  • 优秀网站设计作品域名查询ip
  • 深圳网站制作公司哪家好优化关键词排名提升
  • 怎么样做网站推广seo网络培训机构
  • 网站服务器安全防护怎样做推广营销
  • 电子印章在线制作生成器免费seo搜索引擎实战详解
  • java开发手机app的流程整站优化是什么意思
  • 做兼职的网站 知乎如何做好网络营销推广
  • 深圳装修公司网站网上卖货的平台有哪些
  • 做网站 视频外链今日国内新闻大事件
  • 做超市海报的网站唐山百度seo公司
  • 河源东莞网站建设东莞推广平台有哪些
  • 青岛公司网站建设公司百度百度一下
  • 北京手机软件开发公司宁波seo外包引流推广