上一课时主要介绍了通过 API 管理平台来管理企业内部的 API。持续集成是能够保证软件处于可工作状态的实践,但实施持续集成有一个必不可少的步骤——测试。只有尽可能全面的测试覆盖,才能降低软件出错的概率。但是,大多数企业里还是基于人工来完成测试环节,测试周期长,覆盖率低,使得持续集成的效果并不明显。今天介绍的内容——自动化测试,就是将人工完成的测试尽可能地自动化,从而达到减少测试时间,提高测试覆盖率,提高软件质量的目的。
什么是自动化测试?
首先,明确一下自动化测试不是什么。自动化测试不是指自动化生成测试代码,而是自动化地执行由开发人员或测试人员编写的测试代码。正如下面这句谚语:
绝不要手工去做任何可以被自动化处理的事情。——Curt Hibbs
之前是由人工点击页面上的按钮进行功能测试,人工设置不同的性能参数进行性能测试,都可以通过脚本或测试平台自动化执行。这类测试包含单元测试、组件测试、集成测试和验收测试。也包含一些非功能性测试,如安全测试和性能测试。但有些测试还是需要人工介入,比如用户体验测试、探索性测试等。本课时介绍的自动化测试只包含能够被自动化执行的测试。
为什么要自动化测试?
这个问题可能很多人都能回答几条出来。如“自动化加快了测试速度,缩短了测试时间”,“时间充足了,还可以开发更多的功能”等。下面系统介绍一下自动化测试带来的优势。
& 节约时间和降低执行成本:在软件开发全生命周期中,测试是一个非常频繁且重复的活动。每次提交代码之后,都需要进行测试以确保新的代码变动不会受到影响。在每次软件发版之前,也需要进行系统的回归测试。一旦自动化测试建设完成,就可以做到无人值守运行,甚至可以在多台机器上并行执行。自动化测试大大缩短了测试的时间。
& 减少出错概率,提高准确性:自动化测试每次执行时都会执行相同的步骤,并且每次都会生成详细的测试报告。这些测试报告不受“人”的因素影响。手工测试容易受个人经验和情绪的影响,容易出错,人员的流动又使得测试知识无法沉淀。因此,自动化测试可以减少出错率,提高准确性。
& 提升测试覆盖度:自动化测试可以增加测试的深度和范围,从而提高软件质量。比如,由于自动化测试的速度很快,可以在很短的时间里执行数千个测试用例,从而提高测试的覆盖度。
& 加快反馈效率:自动化测试在每次提交代码之后自动触发,并将测试结果通知到团队中的开发人员,大大缩短了开发人员获得反馈的时间。
& 模拟手工无法测试的场景:自动化测试可以模拟成千上万用户并发访问的场景,这样的测试场景是手工测试无法模拟的。
因此,自动化测试通过快速的批量执行测试用例,减少测试的时间,加速反馈回路,提升软件的质量。另外,使用自动化测试执行那些重复性较强的工作,可以让团队成员有更多的时间研究更有挑战性和更有价值的活动,提高团队工作效率。
如何实现自动化测试
自动化测试能带来很多收益,但实现自动化测试也是需要成本的。很多企业在实施自动化测试时,通常也只能实现了其中的一部分,比如单元测试、代码扫描、冒烟测试等。通过与持续集成流水线进行集成,能够实现代码提交后触发自动化测试,实时反馈测试结果。对于一个企业来说,实施自动化测试的步骤如下:
STEP1:定义自动化测试的范围。
在实施自动化测试之前,先确定哪些类型的测试可以被自动化。根据 Brian Marick 提出的敏捷测试四象限,不同类型的测试可以分为下图几种。
敏捷测试象限表明不同类型的测试有不同的目的,主要的维度包括面向技术还是面向业务、面向支持团队还是面向评价产品。然后根据这几个维度按不同的组合分为四个象限,敏捷测试中涉及的所有测试类型都可以归类到这四个象限中。
第 1 象限:面向业务、评价产品的测试。 主要是业务人员和测试人员执行的测试,测试类型有探索性测试、情景测试、可用性测试和用户验收测试等。测试目标是验证产品功能是否满足业务和终端用户的需求。该象限的测试主要以手工测试为主。
第 2 象限:面向业务、支持团队的测试。 主要是测试人员执行的测试,测试类型有功能测试、用户故事测试、原型测试、模拟测试等。测试目标是验证一个功能或者用户故事是否按验收标准正确实施。该象限的测试主要以自动化测试为主,手工测试为辅。
第 3 象限:面向技术、支持团队的测试。 主要是开发人员执行的测试,测试类型有单元测试、模块测试、集成测试等。测试目标是验证单元模块被正确地实施。该象限的测试主要以自动化为主。
第 4 象限:面向技术、评价产品的测试。 主要是测试人员执行,项目团队配合的测试,测试类型有性能测试、负载测试、安全性测试和其他非功能性测试。测试目标是验证产品是否符合非功能性要求。该象限的测试主要以自动化和手工结合的方式。
从上面敏捷测试四象限可以看出,自动化测试的范围应该在 2,3,4 象限。敏捷测试四象限虽然可以让我们看到相对全面的测试总览,但对于这些测试如何落地还是不够明确,比如哪种类型的测试要多做,要尽早做。
STEP2:定义自动化测试的层次。
敏捷专家 Mike Cohn 在 2003 年提出的测试分层金字塔。该测试金字塔分为三层:底层是单元测试,中间层是服务测试,上层是 UI 测试。这底层的单元测试需要做最多的测试工作,越往上的单元,测试工作越少。根据《谷歌软件测试之道》的经验,这三个层次对于精力投入的比例是:70% 的精力放在单元测试,20% 放在服务测试,而剩下 10% 放在 UI 测试,如图中红框部分。
但从整个测试的过程来看,自动化测试不仅仅是跟代码相关的测试,不仅仅是测试执行过程的自动化,还应该包含测试数据和测试环境的自动化,这里统一称为基础设施的测试。根据经验来看,测试数据和测试环境的准备时间占据了整个测试过程的将近一半的时间。所以可以通过自动化的方式提高基础设施准备的效率。
根据上面的测试分层,从自动化的角度实施不同层次的测试。每一层测试的内容和测试的工具各不相同,比如:
基础设施层,该层主要是准备用于自动化测试的数据和环境。可以使用自动化或者基于容器的方式进行构建。常用的工具有Ansible、Chef、Puppt、Jenkins 等。
单元测试层,该层主要针对代码的方法、类和包进行测试。这些测试一般属于代码级的测试,并与企业内部的持续集成流水线集成。常用的工具有 xUnit 系列工具。
服务测试层,该层主要针对服务之间的接口进行测试。这些测试一般是服务接口之间的交互测试。常用的工具有 Postman、SoapUI 等。
UI 测试层,该层主要针对界面上的功能测试。这些测试一般是在一个或多个应用里进行端到端的流程测试,且应关注重点功能。常用的工具有 Selenium、Appium 等。
STEP3:与持续集成流水线集成。
前面两个步骤确定了自动化测试的范围、分层以及需要使用的工具。第三步就是要搭建自动化测试平台并与持续集成流水线进行集成,自动化测试是实施持续集成实践的重要组成部分,是提交后的代码是否可工作的重要保障。下图是持续集成流水线及自动化测试相关的流程图,其中有些平台在之前的课时中也有讲过,如 API 管理平台和环境部署平台。
上图主要涉及的测试流程是:
1.开发人员提交代码到 Git 仓库或进行分支合并操作。
2.持续集成服务器接收到合并事件后,触发编译构建、单元测试等检查,并将测试结果通知给开发人员。
3.上述检查通过后,部署到 SIT 测试环境中。该环境为集成环境,部署了该服务所依赖的其他组件。当服务部署时即可将 API 接口注册到 API 管理平台,并执行服务之间的 API 接口测试,验证服务集成是否有问题,随后将测试结果通知给开发人员。
4.SIT 测试环境完成测试并达到进阶要求时,即可进入 UAT 测试环境进行用户验收测试。该环境测试主要通过自动化测试平台完成该服务的功能测试。自动化测试平台包含了测试用例管理和测试数据管理。该步骤可以进行精细化地测试策略管理,可以根据代码关联的需求完成该需求相关的测试用例的测试,可以每天晚上执行全量的回归测试。
5.SIT 环境和 UAT 环境等基础设施的管理可以通过环境部署平台完成。环境部署平台可以根据自动化测试的要求,进行定制化的部署和优化设置,并对基础环境进行先决条件检查,确保自动化测试执行之前满足环境的要求。
总结
这一讲主要介绍了通过自动化测试代替手工测试,减少测试执行的时间,提高了测试的效率。将自动化测试集成到持续集成流水线中,可以在提交代码后自动触发测试,从而保证了每次提交代码后的质量,使得软件一直处于可工作状态。本课时的关键内容为与持续集成的流程图和相关组件,自动化测试虽然能带来一定的收益,但自动化测试不是免费的,需要开发相配套的平台来支撑自动化测试有效落地。
测试是软件全生命周期中非常重要的一个阶段。多年来,软件工程的测试专家们也一直在自动化测试的路上不断探索,每家企业也都在或多或少的尝试自动化测试。