作者:上海惠艾首席咨询 郑立
“停止依靠大批量的检验来达到质量标准;依靠大批量检验其实就是等于准备出现次品,这种后道检验出来的结果已经太迟,且成本高而效益低。正确的做法,是改良生产过程。”
--- 戴明(William Edwards Deming)
一、质量内建是什么?
“质量内建作用从开发过程开始,要求软件生命周期之间参与的各个角色都需要实时的对软件的质量负责。确保软件在交付到下一环节前已经有了基础的质量保证。质量内建的过程就是把质量控制向源头不断推进的过程。”
二、 是什么在影响我们的交付效率?
在实践敏捷或DevOps后大家都记住了CICD,但是很少有人重视另一个关键的C,那就是持续反馈CF(Continue Feedback)。忽略CF的原因其实也很简单,那就是每个环节我们只负责交付了可见的成果,但没有交付不可见的质量。当一个事物不可见时,它要么不重要,要么就是即使看到了也被主动忽略,显然研发流程中的持续反馈是属于后者。
所以当我们在全力以赴地从左往右进行交付的时候,很少去关注每个阶段因为质量问题而形成的回头浪。每个回头浪的形成不仅让正向流程负重前行,同时日益积累的问题会最终拖垮流水线的持续交付,使投入了上千万的DevOps平台沦落为只是个简单的部署工具而已。判断是否存在回头浪最简单的方式就是,看我们的研发团队是不是会潜规则地为下个迭代预留20%或更多的时间用于缺陷修复。而根据我们的经验,通过质量内建来预防缺陷的投入可能只需要5-10%的时间,这在投入产出上是非常值得的。
三、为什么测试不能确保质量,
测试后潜在的软件缺陷风险在哪里?
很多人认为软件通过测试就没有质量问题了,其实这个逻辑成立的前提就是错的,验证这个结论最常用的一句话就是“不测就没有缺陷,但是缺陷却客观存在”。究其本质原因,是因为软件质量并不是由测试案例决定的,而是由最终实现该软件功能的代码决定的。换句话说,只有当软件代码没有问题,测试才能通过。所以测试每次只能确保被测部分的代码是功能正常的,但未测代码部分的风险依然存在。理解了这个逻辑,接下来我们再来分析缺陷风险都藏在哪里。
如上图所示,当我们每次为新功能提交增量代码并完成测试后,被测试用例覆盖的区域我们称为“质量防护区”,而潜在的代码逻辑缺陷风险的主要集中在测试完成后未执行的代码,以及跟新功能有关联影响的存量代码,这部分则称为“缺陷逃逸区”。如果不能精准识别“缺陷逃逸区”,无论进行多少次回归测试风险依然存在。
四、如何把缺陷挖掘出来?
要解决该问题就要从根本上下手,我们需要识别测试执行和软件代码关联关系,在每次测试执行时能动态记录每行代码的执行顺序,并对代码是否被执行进行可视化展示。如下图所示,绿色为执行覆盖的代码,红色为未覆盖代码,黄色为逻辑覆盖不全代码。
如果每次测试执行都能实现代码测试覆盖率(TCC - Tested Code Coverage)的统计和呈现,那么增量代码的逻辑风险就无所遁形了。同样的方法不仅可以应用于函数级别,我们可以应用到分支、需求、版本的统计。
对于关联代码,我们则需要识别增量代码和存量代码之间的调用关系,这两者之间的关系静态存在的,只要通过抽象语法树(AST- Abstract Syntax Tree)分析我们就能识别调用函数和被调用函数的关联广度和深度。
通常对于直接调用的函数/方法,我们认为存在影响风险最大,因此也是我们进行回归测试案例覆盖的重点目标。
结合以上分析,我们结合测试代码覆盖率(TCC)和抽象语法树(AST),将所有手工或自动化的“黑盒”测试变成“白盒”测试,再对缺陷逃逸区代码补充测试用例,最终以代码测试覆盖率*案例执行通过率结果作为评价软件质量的指数,即软件质量凭证(注:该指标由Hi-Agile设立)。
在各阶段引入软件质量凭证指标,将能实现上文讲的质量内建定义中:“确保软件在交付到下一环节前已经有了基础的质量保证,质量内建的过程就是把质量控制向源头不断推进的过程”这一目标定义。至此,我们做到了缺陷的防护,实现100%到达TCC很有难度,我们建议循序渐进,通过编码-测试-补用例-再测试这样的方式逐步加强质量守护过程,TCC建议的覆盖率是80%以上。
五、 当我们发现缺陷,
如何快速定位问题代码?
对于在测试中特别是集成测试阶段发现的缺陷,经常有另一个难题困扰开发人员,那就是当缺陷的问题根源不在他所负责的代码领域(或关联应用系统)时,由于日志不全,错误码丢失等各种原因,缺陷根因排查就显得尤为困难。如果这时使用遥测技术(Telemetry),这个问题的解决就显得轻而易举了(注:遥测是通过系统外部输出推导出系统内部状态的一种技术/协议)。
如下图所示,在我们实际执行过程中跟踪了系统的一次运行,并记录了这次系统运行所经历的跨系统的代码链路。
这次执行过程中的发起系统“在线支付”因为各种原因产生了异常(红叹号),根据代码的运行链路我们顺藤摸瓜就找到了Testabs()方法显然报错了。根据异常log和对应的错误代码,我们很快就能找到这次缺陷的问题代码在哪里。通过遥测技术可以让问题定位的效率从几天降到几分钟,而问题分析人员的门槛也从核心开发人员降低到不熟悉代码的测试人员。从这点上讲,对于问题修复的研发成本和周期将同比下降几倍。
六、写在最后
质量内建是对软件质量在工程技术方法上的革新,是基于软件的根本(代码)建立的解决方案。当然质量内建在组织内部的推广也离不开组织的企业文化、工具支撑(Hi-CC)、技术支撑等各方的配套措施。再结合AI在自动化测试的发展,相信未来软件质量领域将有一波新的技术浪潮产生,期待!
而由Hi-Agile业界独创的质量内建实践方法包含了一整套行之有效的方法和工具(Hi-CC),已帮助多家大型金融科技落地实施,显著提升研发效能和交付质量。Hi-CC具有:代码覆盖率统计、各类研发/测试环境的支持、缺陷代码定位、以及与其他系统高度整合性等,详见下面产品介绍。更多详细欢迎前来咨询。