干货 | 如何利用Xcode实现线上代码覆盖率的检查
作者简介
姜睿东,2009年加入携程,从事无线研发,现在大住宿事业群担任酒店无线研发工作。
清理项目中的无用代码是日常开发中非常重要的一环,定期清理废代码既可以保持代码的简洁,也可以让代码逻辑变得更清晰,不给后人留坑。
比较传统的寻找无用代码的做法,一般是查找没有引用的方法或类,这个可以很容易的通过脚本来实现,甚至有的IDE自身就能提供这个功能,再进一步的话也可以在网上找到一些开源算法的脚本,来查找重复或相似的代码。
随着携程酒店业务的快速发展,线上版本的迭代频率越来越快,代码量开始急剧膨胀,以上这些方法已经不够用了。如何及时清理无用的代码,变得越来越困难。
大量的无用代码不是靠检查一下无引用就能发现的,因为我们有着数量庞大的服务端及客户端实验,以及频繁上线下线的业务,靠人肉很难发现哪些是无用代码,而app又对size有着极为苛刻的要求。所以怎么高效率的寻找无用的或利用率极低的代码,成为研究方向。
首先想到的是检查线上代码的覆盖率,没有覆盖到的部分,就是所谓的无用代码。
那么,怎么来检查线上代码的覆盖率呢?网上一般会采用“插桩”的方式,思路就是在代码的每一个函数中植入埋点代码,然后在后台利用一套算法来计算代码的覆盖率,用这种方式得出的结果相对比较精准。但是我们对代码有些洁癖,并不想对代码有任何的破坏,而且这种方式在后台的计算也是相对比较繁琐的。
我们想到的办法是利用Xcode自带的Code Coverage来检查代码的覆盖率。Xcode的这个自带的工具非常的好用,不但可以方便的可视化的看到代码覆盖率,还可以看到代码被执行的频率,如下图所示:
通过这个报表,我们可以很清楚的看到代码被执行的情况,这样就可以针对那些没有被执行到的代码进行具体原因的分析。
但是Code Coverage只能在单元测试的case中才能使用,而单元测试一般用的都是mock数据,酒店业务极其复杂,各种真实数据不太容易造出来,很难真实反映线上代码的执行情况,并不能直接为我们所用。
于是我们把目光投向了我们的自动化测试平台,我们的自动化测试平台有一个流量回放的功能,可以回放线上的真实数据,平时用来自动回归服务端case,存有千万条数据,足以覆盖绝大部分线上的case。
我们设计的大概的流程图是这个样子的:
从图中可以看到,我们的UI测试用例往测试平台发出的是一个空的request,然后由测试平台随机从日志数据库中抽取相应用例的response返回给客户端,如此循环足够多的次数基本上可以覆盖到这个用例的全部case。
这样我们就有了一个理论上可行的应用框架,不过还需要解决一个问题,那就是我们的一个页面上往往有数十个小服务,而且互相之间都有数据依赖,自动化测试平台只能接受单个服务的请求,且无法对应这个服务相关的其他小服务的数据,没有了联动性,就给我们的单元测试带来了麻烦,没有办法完整的测试一个页面。
对此我们又对UI测试和自动化测试平台双双进行了改造,首先在自动化测试服务的api前面,仿造生产环境一样搭建一个Gateway,由这个Gateway来负责json和pb之间协议的转换,如下图所示:
这样的话,我们的单元测试无需在原来业务代码里做太多修改,只需要把原来指向生产Gateway的地址指向自动化测试平台Gateway就可以了,只要几行代码就可以实现一个列表页的测试。
由此我们得到了一个完整的自动化测试线上代码覆盖率的框架,通过不定期的跑自动化UI Case,就可以得出线上代码的真实覆盖率。
【推荐阅读】