前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从精准化测试看ASM在Android中的强势插入-读懂diff

从精准化测试看ASM在Android中的强势插入-读懂diff

作者头像
用户1907613
发布2021-07-19 10:33:32
7140
发布2021-07-19 10:33:32
举报
文章被收录于专栏:Android群英传Android群英传

我们计算增量代码覆盖率的基础,就是要找出两个版本代码的差异,在Git环境下,我们可以很方便的通过Git脚本来获取这些数据。

Git获取diff信息

git diff命令可以使用如下格式,用来对比不同commit(或分支)间的增量代码:

代码语言:javascript
复制
git diff [<options>] <commit> <commit>

其中commit可以是分支名,也可以是commit的id,对比分支间的差异,可以简写为 git diff targetBranchName,表示对比当前分支与目标分支间的代码差异。

下面这张图,就是通过git diff指令获取的一段更新diff信息,如下所示。

代码语言:javascript
复制
git diff HEAD~1 HEAD

输出如下:

image-20210621155525706

diff指令,一定会有两个输入,即A和B,图中第一行,就标记了A和B文件。

对于版本A,它的符号是一个减号(「-」);而对于版本B ,它会使用一个加号(「+」)。

图中的第三四行,就是被标记的两个文件,针对这个标记,存在下面几种情况。

  • diff文件是新增文件,则---后面是/dev/null
  • diff文件被删除,则+++后面是/dev/null
  • diff发生修改,则---和+++后面都有文件名

通过这个,就可以区分文件状态。

Chunk Header

git diff的每个修改,都会生成一个Chunk Header,对应图中的「@@」和「@@」符号之间。

代码语言:javascript
复制
@@ -31,21 +31,25 @@

这里表示,从A版本的第31行开始,变更了21行,B版本从31行开始,变更了25行。

但是,我只是加了4行log啊,这是什么鬼??

其实git diff指令不仅仅会给出变更行,而且还会带上前后默认3行的修改信息,作为上下文,所以才会有这么多的修改。

所以,我们需要再利用git的一个指令:

代码语言:javascript
复制
--unified=<n>,简写为-U<n>

来指定上下文关联的代码行数,这里设置为-U0,表示只关心实际的变更。

加上这个参数后,输出如下:

image-20210625145214250

加了这个参数后,Chunk Header同样会有三种情况:

  • -/+号后面只有一个数字,设为N,那么表示增加(+)、删除(-)了1行,行号为N,例如+34,就是第34行,增加了1行。
  • -/+号后面有两个数字,第1个数字设为N,且第二个数字为0,那么表示第N行没有变化,增加(+)、删除(-)了0行,这有啥意义呢?其实这就表示该内容是新增的。
  • -/+号后面有两个数字,第1个数字设为N,第二个数字为M,那么表示从N行开始,增加(+)、删除(-)了M行,这用于标记多行的修改。

那么有了这样一个认知后,就可以通过正则来检出这些数据。

代码语言:javascript
复制
git diff HEAD~1 HEAD -U0 | ggrep -Po '^\+\+\+ ./\K.*|^@@ -[0-9]+(,[0-9]+)? \+\K[0-9]+(,[0-9]+)?(?= @@)'

借助这样一个正则表达式和grep,就可以从diff信息中找出修改的文件和行号,执行如下:

代码语言:javascript
复制
app/src/main/java/com/yw/qdcoverage/MainActivity.kt
34
40
46
52

这里要注意,Mac下grep是用的2.5.1-FreeBSD版本,所以不支持 -P指令,需要安装GNU Grep,通过brew install grep来安装即可,安装好之后,通过ggrep来调用GNU Grep(如果是Linux的话,那么可以直接使用grep)。

如果在脚本中,可以借助正则表达式来获取。

代码语言:javascript
复制
Pattern.compile("^@@ -(\\d+),?(\\d+)? \\+(\\d+),?(\\d+)? @@.*");

这样通过下面的代码就可以获取新文件的修改行:

代码语言:javascript
复制
matcher.group(3)
matcher.group(4)

以上就是我们获取增量信息的基础,借助git的这些指令,我们就为后续JaCoco探针的插入,提供了Diff的信息,从而可以实现增量探针机制。

向大家推荐下我的网站 https://xuyisheng.top/ 点击原文一键直达

专注 Android-Kotlin-Flutter 欢迎大家访问

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 群英传 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Git获取diff信息
  • Chunk Header
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档