现代软件工程和敏捷开发强调拥抱变化,除了对软件系统设计和实现的高质量要求之外,持续集成(Continous Integration)也成为高质量交付的重要一环,这对于包括测试工程师在内的开发团队而言极具挑战性。本文将分享测试工程师如何拥抱未来,与时俱进,持续提升自我修养。
PART 01 测试工程师面临的新挑战
敏捷开发概念从提出到现在已经有二十年左右的历史了,它的核心是“快速响应,持续交付价值”。软件开发过程非常强调人的重要性,开发团队要能做到团结协作。人与人的交流、沟通要面对面,而非制定详细的文档,按预定的计划逐一进行开发、测试。变化是敏捷开发过程中唯一的不变。
开发快速提交可测试的代码,也必然要求测试可快速地验证提交代码的可用性及稳定性,简单的手工测试已经无法满足需求了。
在敏捷初始,测试开发阶段环境的维护部署基本是QA或开发自行完成的,这些工作也基本都是手动去操作的。同时,每个Scrum团队所侧重的点不同,因而容易忽略其他服务,导致测试环境与线上运行环境有些许的差异,上线后就可能存在兼容性或完整性的问题。
在整个开发及测试阶段,我们要不停地重复一些工作,如修改bug、部署新包、验证bug、记录新bug等,全线环境也要保持同步的修改部署。由人手动去部署环境可能会花费比较多的时间,也可能会因为人为操作失误引起不必要的问题,造成整个团队无法进行工作而影响项目周期。
我们面临的问题是:
- 跨域跨部门合作,而不只面对面;
- 如何提高效率,做到快速交付;
- 如何降低人的干预降低出错的可能性。
PART 02 DevOps的应用
我们认为,DevOps可解决如上问题。
什么是DevOps?*给出的定义是:DevOps(Development和Operations的组合词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。
DevOps表面上是开发与运维的结合,实际它是一个过程、方法与系统的统称。
DevOps过程周期:
理想的DevOps周期开始于:
- 开发编写代码;
- 自动化编译出包并自动部署到测试环境;
- 执行自动化测试用例并发布;
- 自动化部署到产线环境。
很显然,DevOps过程中非常强调构建、部署和测试的自动化,在DevOps周期中使用持续集成工具、自动化测试工具。
在DevOps中测试角色也会发生变化:
传统模式下,测试人员的主要工作是执行他们的功能及回归测试。在测试人员正式验收完毕测试包前,构建人员一般会跟测试人员坐在一起工作一段时间,在DevOps中这将会发生改变:
- 由原来的手工测试转为自动化测试,要尽量将所有的用例都自动化,并可达到100%代码覆盖;
- 要确保测试环境与产线环境一致,并可自动化部署;
- 测试前任务,清理工作及测试后任务都已自动化并可分配到持续集成的过程中。
DevOps中需要高度的协作,各个角色职责边界也变得模糊,鼓励每个人作出自己的贡献,开发人员可以配置部署工作,部署人员可以添加测试用例到QA的用例库中,测试人员可以配置修改DevOps链路中的用例。
现在及未来对测试人员的要求会越来越高,简单的黑盒测试将无法达到期望。
DevOps是未来,而自动化是DevOps成功的核心。作为一名测试人员要把自动化作为职业发展的重要方向,专项知识加上自动化技能才可以更好地服务于产品的快速迭代。
PART 03 自动化测试实践
从上面的分析我们可以看出自动化测试在整个产品周期中起的作用,那么我们应该如何开展?
自动化测试金字塔
从图可以看出,除了单元测试外,API级的自动化测试可以达到比较高的测试覆盖率。所以我们从API测试自动化入手,一是利用它我们可以完成场景用例,更接近用户的使用;二是相对UI自动化测试,它更稳定。
拍乐云的测试工程师开发了一套API自动化测试框架,我们用该框架做如下自动化的开发:
- 功能用例自动化
- 模拟用户调用接口习惯
- 性能测试
- 质量测试
拍乐云API自动化框架
拍乐云是为用户提供实时音视频服务的,我们志在为用户提供易用、高质量的产品。我们不局限用户调用接口的方式,用户可按自己的习惯及理解去使用服务,这对产品的鲁棒性要求就更高。
我们的测试工程师基于对外API层来做自动化测试,通过了解产品接口就模拟用户使用习惯方面设计接口测试用例,主要从如下几个方面考虑:
- 变化接口参数
- 变化接口调用顺序
- 变化接口调用条件
自动化的目的之一是节省人力成本,利用接口测试来做功能用例的自动化也是这个目的。在这个场景下,我们主要侧重于回归测试用例。随着功能的增加,回归的成本会越来越高。故功能回归集也会随着功能的增加不断的扩大。我们把回归用例集分为两部分:
- 基础用例,保障基本功能
- 详细用例集,包括更多的功能逻辑
这两部分各有不同的作用,基础用例用于构建pipeline,验证新代码是否影响基本功能的使用,这样既不遗漏功能,又可减轻pipeline的负载。详细用例集用于验证更复杂的用户使用场景,主要应用于测试环境的功能测试,以达到一定的覆盖率,进一步保障功能的可用性。
在我们的日常发布中,会有一定的性能测试,如媒体服务器的并发能力,音视频在特定设备上的性能表现等。性能数据是产品稳定性的体现。性能测试的重点在于场景定义,在场景一定的情况,确定性能瓶颈。如一个Media Server可以支持多大规模的大会;一定配置的MediaServer可以同时开多少个六人会议,这六人中一人发送一路720p及接收5x180p ,其他人都发送1路180p接收1路720p+4路180p等,我们会根据自己的需求获取相关场景的性能数据作为基准,也会根据多数用户实际使用场景或用户需求来定义性能场景。
六人会议一人发送720p+接收5路180p,其他五人发送180p接收1x720p+4x180p
媒体服务性能指标我们会关注CPU、Memory及网络吞吐量。
还有端的性能,这个数据除了跟场景相关外还和设备本身的配置有关,如相同场景iPhoneX与iPhone13 Pro的表现肯定不同,iPhone13 Pro 可以稳定并长时间编码720px30f及解码1路720px30f,而iPhoneX相同的场景可能持续不了1小时甚至更短就会出现编码降帧率或分辨率的情况。故设备上的性能我们除了关注CPU、Memory的使用外,还会关注设备上所能支持相应视频规格的时长,当然还有耗电情况等。
通过功能用例,模拟用户调用场景,性能及质量测试的自动化,我们可以达到大约50%的覆盖率。除了接口自动化,我们还应用了UI自动化,主要应用到我们对外app的产品形态上。
API级自动化测试将是我们自动化的重点,我们会继续提升它的作用,未来我们会加强如下工作:
- 及时添加接口用例,我们希望可以做到Test Driven Development;
- 攻克难点功能,如白板,因为白板会涉及到交互操作功能,故导致我们目前有些自动化无法全部实现;
- 结合接口自动化实现质量测试的自动化。