马蜂窝技术原创内容,更多干货请关注公众号:mfwtech
测试覆盖率常被用来衡量测试的充分性和完整性,也是测试有效性的一个度量。「敏捷开发」的大潮之下,如何在快速迭代的同时保证对被测代码的覆盖度和产品质量,是一个很是有挑战性的话题。前端
在马蜂窝大交通、酒店等交易相关业务中,项目的开发和测试实践一样遵循敏捷的原则,迭代周期短、速度快。所以,如何依据测试覆盖率数据帮助咱们有效判断项目质量、了解测试状态、提高迭代效率,是咱们一直很重视的工做。java
对于功能测试而言,一般能够经过充分了解需求、完善的测试用例、接口测试、Review 技术方案等来保证测试充分性。但随着业务规模快速发展,业务逻辑愈来愈复杂,系统级别交互愈来愈多,这些方法都不能保证全部的代码必定被所有测试过,也给测试人员带来极大挑战。数据库
说到这儿和你们分享一个由于测试覆盖不充分,影响到线上业务的真实案例。事件原由是项目提测阶段一个微服务 Sonar 扫描没经过,开发同窗为了修复 Sonar 发现的问题而重构了一部分历史代码,却致使一个原有发券需求的错误。当天下午运营触发发券后 Bug 出现直接致使生单不可用,而且持续了将近一个小时。这里的问题就是发券功能与这次需求无关,开发人员修改代码后测试人员不知道,也没有通过测试,但跟随本次需求一块儿上线了,测试用例没法覆盖到。后端
经过这个例子能够明显地看到正确统计被测代码覆盖率的重要性。当前市面上统计覆盖率的工具不少,但应用到咱们的实际场景中一般存在如下问题:浏览器
所以,大交通测试组决定自研工具进行被测代码的覆盖率统计,用代码覆盖结果反向地检查测试人员测试用例的覆盖度和开发人员代码的冗余度,更精准地定位和分析问题,保证产品质量。服务器
结合咱们的实际场景,覆盖率统计工具的实现目标以下:架构
咱们将覆盖率统计工具命名为 jCover,并将其引入 CI/CD 体系,与内部 Java 平台项目管理及持续集成系统 MONE 打通。工具设计以下图所示:微服务
图 1:覆盖率工具总体架构图工具
覆盖率统计的大体流程为首先经过获取多环境服务的配置信息,生成指定环境服务的测试覆盖率文件,而后根据须要生成全量覆盖率报告和增量覆盖率报告,最后,存储测试覆盖率报告到指定环境目录下。单元测试
jCover 的主要功能包括:
下面围绕以上功能点,为你们介绍 jCover 的做用、特色和具体实现方式。
为了简化操做步骤下降学习成本、报告简单易懂,jCover 支持界面化操做,能够手动生成测试覆盖率报告和查询测试覆盖率报告;查询测试覆盖率报告入口统一,代码测试覆盖率数据清晰,方便数据统计和量化。
图 2:覆盖率报告查询页面
因为使用敏捷迭代,项目多、并行率高,大交通全部微服务均引入测试环境隔离插件,同时支持多项目并行测试。所以,jCover 须要支持多环境并行的测试覆盖率统计。
具体来讲,每一个测试项目都会有一个单独的环境标识,以隔离环境标识+环境类型+服务名称惟一肯定一个覆盖率统计单元;每个覆盖率统计单元都会生成对应的测试覆盖率统计报告,测试覆盖率统计报告被存储到 jCover 部署的服务器中,存储位置是环境标识对应的服务目录下;同一个服务的不一样提测分支同时在多项目中测试时相互间的覆盖率报告不会被覆盖。
多环境并行流程图见下图(目前只支持 QA 环境覆盖率统计):
图 3:多环境并行流程图
例如:隔离环境 gjssqz 和隔离环境 supplyrefund 能够同时进行测试覆盖率统计,隔离环境标识+环境类型+服务名称指定了每一个环境下的单个服务测试覆盖率统计结果。
覆盖率工具 UI 展现以下图:
图 4:用「隔离环境标识+环境类型+服务名称」来标识和统计覆盖率
在测试时有时候须要关注全量代码的测试覆盖率,代码全量覆盖率统计过程以下:
(1)查询服务信息
jCover 经过内部 Java 平台项目管理及持续集成系统 MONE 来查询被测微服务的信息:
(2)收集覆盖率数据
为了作覆盖率统计,须要从微服务部署的容器中下载测试覆盖率 Dump 文件。咱们采用的解决方案是使用 JavaAgent 代理,首先对微服务部署的容器进行了改造,使得容器支持 JavaAgent 功能;其次为了动态插桩记录被测代码的运行结果,在被测微服务的 JVM 启动脚本中增长 JavaAgent 参数。
覆盖率工具根据 IP 和监听端口经过 JavaAgent 代理从容器中下载 Dump 文件,以环境和服务标识惟一 Dump 文件,并存储到 jCover 所在的服务器。在下载覆盖率数据时采用追加方式,若是该 Dump 覆盖率文件已存在,那么该轮的覆盖率数据会直接在文本末尾进行追加,便于统计整个测试过程的代码覆盖结果。
(3)根据全量覆盖率文件生成全量覆盖率报告
用户打开测试覆盖率工具前端界面就能够在浏览器中查看步骤 D 生成的覆盖率报告了,绿色表示被覆盖,红色表示未被覆盖,黄色表示部分覆盖:
图 5:全量测试覆盖率报告展现
业务发展到必定阶段后,代码量级很大。主干代码咱们默认是正确的代码。当一个新需求提测后,测试人员更关注的实际上是针对本次需求更改的代码的覆盖率而不是所有代码的覆盖率,想从全量覆盖率报告中找出本次更改的增量代码的覆盖率是很是困难的。基于此问题咱们开发了增量覆盖率统计功能。
增量覆盖率统计和全量覆盖率统计有三个相同的步骤:查询服务信息、收集覆盖率数据、生成全量覆盖率文件。生成全量覆盖率文件后,增量覆盖率统计的不一样点是增长了如下处理:增量代码获取、生成增量覆盖率报告,具体实现以下:
(1)Diff 增量代码
(2)生成增量覆盖率报告
图 6:增量覆盖率流程
下图是交易服务增量覆盖率报告的截图示例,从图中清晰看出增量行和更新行的测试覆盖率状况。
图 7:增量覆盖率报告展现
当测试人员须要查看最新的测试覆盖率时,能够经过「jCover - 生成测试覆盖率报告」的入口手动触发生成测试覆盖率报告。
图 8:手动统计覆盖率图形化界面
在一个需求的实际测试中被测的微服务一般有多个。由于修改 Bug 等缘由,被测微服务常常须要重启,重启后容器销毁,JavaAgent 插桩后的文件也会被删除致使重启前覆盖的代码没法被统计。
若是每次重启每一个被测微服务前都须要测试人员手动生成覆盖率报告的话,是个很大的工做量也会常常被遗忘。所以 jCover 经过和发布系统结合实现了覆盖率自动统计功能。具体实现方法为 jCover 提供了自动生成覆盖率文件接口,在服务重启部署时后端发布系统调用此接口,实现自动统计覆盖率,无论服务重启多少次均可以把每次测试时覆盖的代码所有统计到。
以前大交通的后端服务发布系统为 Jenkins,后续升级为了 MONE,两种发布系统下均支持服务部署时自动统计覆盖率。
通过一段时间推广使用和优化,如今大交通全部的需求提测后均使用 jCover,主要体现出如下几点优点:
目前 jCover 只支持查看每个类覆盖行和未覆盖行是什么,可是对于一个微服务总体行覆盖率是多少没有统计,咱们正在开发增量覆盖率百分比,帮助开发和测试作出准确的判断。目前也在调研前端的覆盖率统计,下一步将实现前端的覆盖率统计工具 jCover。
在平常需求测试中能够采用测试(手工测试、接口测试、回归测试等)+jCover 覆盖分析的测试方法来完善测试场景,减小测试遗漏,确保测试的充分性,但须要注意的是 jCover 统计只能展现哪些代码被覆盖了,代码的正确性仍是须要用例的执行结果正确来保障;还有时候开发会漏开发某部分需求,此时依靠 jCover 是没法发现这部分遗漏代码的,所以除了 jCover 以外能够经过参与技术评审、编写用例时参考产品功能矩阵图等多种手段发现问题,全方位保障被测代码的质量。
以上就是对马蜂窝大交通测试覆盖率统计工具 jCover 的分享。固然,统计代码覆盖率仅仅是一种手段,覆盖率高不必定表明质量好,但覆盖率不高的代码质量风险确定很高。只有清楚在覆盖率统计数据背后反映出的问题,才能从根本上保证软件总体的质量。
本文做者:代春美,马蜂窝测试部-交易测试工程师;孙海燕,马蜂窝测试部-交易测试团队负责人。