自动化测试在京东数科的实践与探索
一、了解什么是DevOps
DevOps的目标是实现软件系统的快速交付、并且提升系统稳定性和获得用户良好的反馈。不知道是不是有些同学和我一样,仅仅靠单纯概念性的描述比较难以理解什么是DevOps。
就好像我们常常说要养成“良好的生活习惯”,那这个“良好的生活习惯”可能会包含:早睡早起、健康饮食和合理锻炼锻炼等等具体的行为。其实DevOps这个有点抽象的概念也是由一系列具体的行为和软件工程实践组成的。包含:基础设施即代码、CI/CD、自动化测试、容器化、服务编排、自动化部署和软件度量等。
CI/CD流水线是决定系统能否实现快速交付的关键所在,也是DevOps实践中关键的一环。
图1:DevOps模式
二、自动化测试的困境
而在研发团队的实践过程中,自动化测试往往是一个比较难啃的硬骨头。我列出其中两个困难点:
自动化测试需要持续不断投入,自动化测试脚本和代码的开发工作量不小于实际业务代码的开发工作量;
构建CI/CD流水线系统的团队往往是独立于业务研发团队而存在的,而其中自动化测试环节却需要业务研发团队的配合才能够良好实施。
在众多的研发团队中,有一些负责质量效能的团队是自动化测试的先行者。他们能够抽出专门的资源来编写自动化测试用例;并通过自己搭建Jenkins来实现自动化测试用例的夜间定时执行;还有些团队自己开发了测试平台实现自动化测试用例管理、执行和度量等功能。但是这种各自独立的自动化测试平台又存在以下问题:
按照各自平台标准开发的自动化测试用例,由于技术框架不同等原因,并不能实现资源共享和重用。
自动化测试相关数据都是存在各自的平台中,当需要在更大范围内对不同应用或系统的自动化测试程序进行度量和评估时,由于标准不统一和数据不互通而导致难以实现。
自动化测试的机器资源有限,常常由于执行资源受限而影响自动化测试的运行效率。而且不时会由于执行机器的偶发性故障影响自动化测试执行的稳定性。
自动化测试常常通过手动触发或者定时触发执行,并没有与实际的研发流程结合起来。研发在进行日常特性功能开发、变更的提测、合并主干和发布上线等操作的时候,并没有实现实时触发自动化测试的执行,
三、破局之道
笔者所在的团队已经为公司内部提供了一套完整的DevOps工具方案,从迭代管理、代码仓库、分支策略、编译构建、静态代码分析、单元测试、测试环境部署、自动化测试到线上发布,贯穿了整个研发过程。
下面重点介绍下自动化测试子系统如何结合实际业务场景来解决研发过程中的痛点。说起自动化测试的实现方式,笔者以目前通用的实现方案为例,从是否需要写代码的角度来分析下其优劣:
1、需要写代码的自动化测试
优点:灵活性强,可以基于不同的XUnit测试框架(例如基于Java语言的Junit、TestNG;基于Python的Pytest、Unittest等)来实现自动化测试代码的编写。对于测试开发工程师来说,使用原生的框架来通过写代码的方式实现自动化测试,有利于自身的技能提升,能够学到更多的东西。
缺点:有一定门槛,有些测试同学缺乏编码能力,要想写自动化测试代码,需要首先学习基本的编程语言语法,还需要学习测试框架的基本使用。
2. 不需要写代码的自动化测试
优点:上手简单,成本低;测试工程师不需要掌握编程技能,便可以通过页面配置的方式来编写一个自动化测试用例(参考Postman等工具)。
缺点:扩展能力较差,操作步骤和配置项较繁琐。不像基于代码来实现自动化测试有强大的扩展能力,而且一般有较多的配置项,需要通过较多的步骤和配置来实现复杂业务场景。
而笔者目前所在团队开发的JAT自动化测试子系统,支持以上两种方式来实现自动化测试。用户既可以通过编写Java代码的方式,也可以通过页面配置化的方式来实现自动化测试。
JAT自动化测试平台致力于解决研发过程的测试痛点,其目标是为各业务研发团队提供自动化测试的基础能力,包含测试生成、测试执行和测试度量等。通过与持续集成流水线的集成和在研发过程中的内嵌,在保障系统高质量的前提下,使用自动化的手段逐步提升研发团队的交付效率,从而实现DevOps的落地。
下面重点介绍下针对基于TestNG框架编写的自动化的功能特性:
1、实现测试工程的规范化
通过一键生成测试工程脚手架来规范工程的结构目录和相关配置:
图2:生成测试工程脚手架
对于外部导入的测试工程会首先进行目录结构和配置的规范检查:
图3:导入测试工程规范检查
2、实现测试方法的平台可视化展示和数据统一度量
将测试方法在平台上可视化展示出来:
图4:测试方法可视化展示
实现产品级测试数据的统一汇总和展示:
图5:测试数据展示
由原来直接拉取测试工程代码通过Maven命令执行,改为打包服务和执行服务分离,采用先构建测试包,再发到测试区执行的方式。这种把测试代码管理和执行服务分开的方式,能够满足对测试代码管理比较严格的诉求,可以避免把测试代码直接拉到测试执行环境,从而一定程度上控制测试代码的扩散和外漏风险。
图6:测试工程打包与执行分离
4、实现与CI/CD流水线系统(JCI)的对接
如果是手动触发或者定时执行的自动化测试计划,那么只需要在JAT平台上创建相应的测试计划就可以了。
而想要实现一个持续集成流水线,也就是当代码变更时,能触发拉取代码、编译构建、环境部署和自动化测试执行一连串的操作。就需要在JCI系统里配置一个自定义流水线来实现。
图7:CI流水线中的自动化测试
目前是通过测试套件(TestNG测试套件)的方式与流水线集成,后续还会支持通过测试计划的方式与流水线集成,也就是在流水线中可以选择该产品/应用下属的自动化测试计划。
四、未来展望
为了更好的支持研发团队的DevOps实践落地,JAT自动化测试平台后续计划在以下几点继续丰富功能:
接口自动化测试用例的自动生成:能够进一步简化编写自动化用例的成本;基于被测应用服务的源码和配置等信息,自动生成门槛覆盖率的自动化测试用例,并一键创建测试计划,从而满足最基本的基本功能回归测试需求。
自动化测试的精准度量:在目前接口覆盖率和代码覆盖率的基础上,实现产品/应用代码覆盖率及变更代码覆盖多维度的度量。给研发提测、部署和发布等操作提供更加精确和可参考的自动化测试数据 。
进一步丰富持续测试功能:在目前对接自定义流水线的基础上,进一步增加流水线触发自动化测试执行的场景;并且能够实现自动化测试结果数据与CI/CD流水线系统(JCI)上的其他研发过程数据的深度整合,比如自动化测试覆盖率与功能测试覆盖率的数据合并计算等。