本文由 dbaplus 社群授权转载。
当下的 IT 领域,持续测试是成功采用 DevOps 交付模式的关键因素。持续交付的目标,是能够快速和持续地反馈符合客户需求的高质量产品。
然而,理想很丰满,现实很骨感。自从 2012 年,第一份 DevOps 报告由 Alana Brown 发布之后,DevOps 开始逐渐获得业界的认知。越来越多来自各领域和产业的 IT 团队开始谈论 DevOps 和数字化转型,其中不少团队已经根据自身对 DevOps 的理解采取了行动。根据哈佛商业评论的数据,在 2019 年大约有 70%的转型项目失败,而失败的原因与其 DevOps 落地的情况有着很强的相关性。
本文我们具体来看看,现阶段持续测试是如何帮助团队成功落地并实现 DevOps 转型的。
一、避免中心化的测试团队
传统上来说,QA、开发和产品 Owner 隶属于不同的团队,即烟囱式的中心化团队。当开发完成一个功能需求的开发之后,QA 团队才开始测试用例的设计,并且执行对应的测试用例,无论是手工测试还是自动化测试。当所有的测试工作结束后,产品负责人会验收这个新开发的功能是否符合预期。通常在这种开发模式下,QA 团队或者产品 Onwer 的反馈已经晚了,因为代码已经被合并到了主干,导致任何代码的变化将造成的成本已经高出了大多数人的预期。下图是一个传统的中心化的团队结构:
DevOps 的核心观念就是提供反馈,为开发团队尽早地提供反馈机制对于实现持续集成至关重要。因此,团队的结构应该被调整为如下图所示:
在新的开发测试运维一体化的团队中,QA 将作为核心团队的一部分,和开发、产品一起来创建用户需求用例和测试用例,甚至测试用例开始的时间点,会比开发开始写下第一行代码的时间点更早。
二、定义测试类别
下图是一个描述测试类别的分类图。在现实中,很多团队并不清楚自己对于不同的测试类型扮演什么不同的角色、承担哪些不同的责任。
手工探索性测试(Owner Product Owners)
手工探索性测试通常是由来自业务团队、或产品团队的代表最终用户的领域专家来承担,这些专家对于产品如何在真实的生产环境中使用非常清楚和自信。手工探索性测试通常是对一些常见的场景进行具有创造性的验证,模拟在现实中有可能会发生的场景。
UI 回归测试(Owner QA engineers)
UI 测试一般会被定义为回归测试,由 QA 工程师进行维护。UI 自动化测试脚本的维护成本是非常高的,而且对于 QA 工程师的技能有比较高的要求。因为在执行 UI 自动化测试的成本通常高于接口测试,因此,UI 自动化测试不应该被用来当做一个检查点来确定代码是否应该被合入。
这是因为,如果 UI 自动化回归测试失败之后,QA 工程师、开发,甚至产品人员应该坐在一起,来检查自动化回归测试是否应该被更新。在这一点上,开发可以去做性能重构或者安全重构而不用担心自己新的代码会影响现有功能。
UI 测试通常被设定为每天执行,用来执行 UI 自动化测试的编译包通常被称为 snapshot 版本或者黑夜版本。
服务接口测试(Owner Developers, QA engineers)
服务接口测试通常由开发人员,少数情况由测试人员来进行维护。开发人员需要确保自己合入主干分支的代码能够符合需求。通常情况下,服务接口测试的开发会早于业务代码的开发。开发人员在开发业务代码的时候,需要保证业务代码的功能能够通过服务接口测试的测试用例。
这个流程在业界被称为测试驱动开发(TDD,Test Driven Development)。如果被合并入主干的代码导致了服务接口测试用例的失败,这个问题必须立刻解决。开发人员应该首先关注如何将业务代码通过服务接口测试用例,在通过用例之后,开发人员就会对接下来代码性能或者安全的重构不会影响业务逻辑而很有信心。
单元测试作为代码质量的门限(Owner Developers)
单元测试应该关注单个类或者方法。需要注意的是,代码会腐败。开发人员应该对自己代码的 code smell(即代码风格)承担责任,并且遵守团队的代码规约。从 DevOps 的角度来看,代码的单元覆盖率应该在代码被合并到主干分支之前被保证。
通常,一个 Pull Request(PR)被创建之后,单元测试覆盖率应该被自动化的工具检查,并且在正式的代码人工审查之前,保证单元覆盖率和代码规约质量符合团队的规范。这么做有两个优点,其一是强迫开发人员在代码人工审查开始之前就注意代码质量,其二是团队在做人工审查的时候能够关心真正的逻辑问题和代码设计问题,而不是一些基本的代码错误,节省整个团队的时间。
三、自动化测试数据管理
自动化测试数据管理是一个很大的话题,而且是实现自动化测试的重要因素。通常,测试数据管理会被与测试环境管理混为一谈,但是,我个人更愿意将测试数据管理分开来谈,主要有以下几个考量。
环境管理关注部署
环境管理的目标是保证环境的一致性。这意味着我们必须保证基础设施和配置在测试的所有环节保持一致。部署完成后,在运行测试用例时,环境不能有变化。这一点和测试数据是不同的。
在数据中心或者公有云环境下,环境的创建本身也类似于代码的管理,自动化构建的脚本和流水线,将会获取环境的定义,通常环境定义本身也会使用 git 仓库来保存,进而触发环境构建的流程。实例的初始化流程脚本也会从一个共享的配置管理数据库(CMDB)中获取配置信息来创建环境的实例。流程如下图所示:
测试数据管理和测试用例的关联关系
不同于环境管理,测试数据的设置和初始化需要和测试用例关联。我们需要找出基础数据和测试用例数据。
基础数据,有些团队称之为参考数据,是一个标准的参考数据模版,用于所有的测试环境,并且独立于测试用例。所有的测试用例都需要建立在基础数据之上。每一次测试数据需要恢复到初始状态时,测试人员就可以使用基础数据覆盖当前环境中的数据集来“恢复出厂设置”。
测试用例数据是在每一次执行测试用例之前,自动化引擎将会从测试数据管理平台(Testing Data Management)获取用于初始化测试数据的增量数据。执行测试用例之后,清理工作将会把产生的中间数据清理掉,并且恢复到测试用例之前的测试数据集。因此,测试数据的准备和清理都必须做到幂等。
具体流程如下图所示:
结论
测试部分通常因为更重原因,例如成本考虑、团队结构考虑,或者政治因素,在落地 DevOps 实践中被有意或者无意地忽略。但是,实际上测试才是实现真正的持续集成和持续交付的关键点。请注意,持续测试不仅仅是工具和技术,更是一个流程、组织结构和思维方式。
作者介绍:
赵辉,前 HSBC 商业银行 DevOps 团队主管,DevOps 专家,现任一线公有云企业 DevOps 平台解决方案架构师。
原文链接:
评论