深度实践微服务测试
上QQ阅读APP看书,第一时间看更新

2.1 传统测试策略与敏捷测试策略

关于测试策略中应该具体包含哪些内容,在传统开发模式和敏捷开发模式下是不同的。在传统开发模式下,测试策略不仅作为测试设计的指导,而且是测试流程中重要的交付物,它包含相当多的内容。而在敏捷模式下的测试策略强调的是测试的指导思想,并没有定义严格的流程。下面来简要介绍下这两种测试策略,便于我们更好理解微服务中的测试策略。

2.1.1 传统测试策略

在传统模式下,常见的测试策略内容包括测试范围、测试方法、测试环境、测试工具、发布控制、风险分析。

(1)测试范围

在早期我们测试什么,通常是由测试经理基于需求跟踪矩阵(requirements traceability matrix)并结合经验来判断。例如,测试应该包括哪些功能、哪些模块、运行哪些用例,最终通过需求跟踪矩阵与开发经理讨论获得(对本次修改的特性或组件,加上高风险的特性与模块进行回归分析)。而今,得益于Git历史记录、代码覆盖率工具,以及依赖分析技术的发展,我们可以相对客观地获取本次测试的影响范围。在笔者参与过的微服务项目中,就曾利用Git记录来判断测试范围。

(2)测试方法

测试方法通常涵盖测试层级与类型,如测试需要考虑单元测试、集成测试、组件测试、端到端测试、回归测试、性能测试、安全测试等。测试方法还包括测试流程,从需求到发布过程中不同的阶段对应哪些测试活动,在这些活动中,每种角色应该有怎样的职责。有些测试方法还可能会包括自动化测试的策略、缺陷的管理策略。

(3)测试环境

测试环境包括测试环境的种类与数量、不同测试环境的构建方式等,有时还会包括对测试数据的管理,例如是采用构造的假数据,还是利用脱敏的真实数据等。

(4)测试工具

测试工具包括测试管理工具、测试执行类工具等。对于测试管理工具,要考虑是否需要专业的测试用例管理系统,如果是,使用哪种测试用例管理系统;又如缺陷管理是否应该与需求管理共用一个系统;哪些缺陷需要记录及不同阶段的缺陷是否采用不同的系统来记录等。此外,测试中可能还会用到测试执行类工具,如自动化测试工具、API测试工具、性能测试工具以及安全测试工具等。

(5)发布控制

发布控制要确保该发布版本中所有修改都能得到全面测试,并明确测试到什么程度可以达到发布的标准(即测试准出标准)。

(6)风险分析

风险分析涵盖测试过程中所有影响测试效果的风险,以及其应对方案。除罗列风险外,通常需要给出应对手段,以进行主动规避或者减轻其影响。常见的风险包括:第三方依赖未能及时上线导致难以完成系统测试;选取的测试工具不能实现某些场景测试,导致给定时间内无法完成对这些场景的测试覆盖等。

传统的测试策略文档很大程度上承担了与多方项目干系人就测试策略达成共识的任务。在传统的瀑布流模式下,软件开发的速度较慢,每个阶段都是分开的,因此需要详尽的文档来确保大家在不同阶段的理解是一致的。而在敏捷模式下,软件开发速度很快,开发人员与测试人员都围绕故事卡进行增量开发与增量测试,软件迭代式演进。详细且复杂的测试策略文档对一个前期频繁变化的软件而言是难以参照实施的,而且敏捷本身强调“可工作的软件高于详尽的文档”,因此取而代之的是更高维度的思维框架。但需要澄清的是,敏捷测试并非没有任何文档,而是强调编写必要的文档。

2.1.2 敏捷测试策略

敏捷创始之初的核心是敏捷宣言,敏捷宣言中的核心思想是要定义价值观而不是定义流程,这一点与传统瀑布模式非常不同。作为敏捷开发的重要组成部分,敏捷测试同样未被明确地定义到底如何做,因此敏捷测试中更加强调策略胜过具体的测试流程与测试动作。在敏捷测试发展的历史中出现了一些用于制定敏捷测试策略的重要思想框架。

敏捷开发中常用的测试策略框架有2个:一个是敏捷测试象限,另一个是测试金字塔。

1. 敏捷测试象限

图2-1是大家最为熟知的测试象限版本,它来自Lisa Crispin的Agile Testing一书。

图2-1 敏捷测试象限(Lisa Crispin版)

而在此之前有一个更早期的版本,即图2-2所示Brian Marick的测试矩阵(Test Matrix)。

图2-2 测试矩阵(Brian Marick版)

Lisa在其博客中也声明了自己的版本源于Brian的版本。从两个图的对比看出,Brian的版本没有给出具体的测试类型,而是通过定义测试的类别来指导测试工作。这也是测试象限的最重要价值。当从高层次设计测试时,它提醒我们需要考虑4个广义测试类别,具体如下。

1)面向技术、支持编程的测试:保证开发人员在正确地做事、高效地做事,其包含两类。一类是引导开发者开发程序的技术性测试,通常指TDD中的测试,典型的代表是模块间接口、模块的方法所编写的测试。另一类则是作为防护网的测试,通常是为了检测代码的行为变化而后补的测试,例如对重要逻辑后补的单元测试等,一般为低层级测试。

2)面向业务、支持团队的测试:从产品的角度来设计测试,指导团队开发出的程序做正确的事,确保团队所开发的产品是正确的,其包含两类。一类是先编写的验收测试,然后利用BDD进行行为驱动开发。另一类也是后补的测试,常见的是针对故事卡中的验收条件所设计的扩展性测试用例,也是我们最常见的测试。它们通常在程序完成后用于验证,并在未来作为回归测试用例来使用。

3)面向业务、评价产品的测试:是从用户使用产品的角度,验证团队是否在做好的产品。这里的测试更多是指探索性测试、用户真实使用场景测试、易用性测试等。

4)面向技术、评价产品的测试:前面3类测试更多时候需要的是通用的测试能力,而需要特殊的技能才能完成的测试会落入这个象限,如性能、安全、易用性测试等,这类测试通常在专业人士的引导下才能设计出来。

我们之所以溯源回最早期的版本,就是为了说明之前的测试矩阵更具有普适性,更加符合敏捷的特点,即“响应变化”。也就是说,测试象限里具体的测试类型会针对被测试系统的不同而变化,但这4个大的类别是我们在定测试策略时需要考虑的重要维度。

稍后,我们会针对微服务架构画出对应的测试象限。

2. 测试金字塔

图2-3是Mike Cohn版本的测试金字塔,最早用于制定指导自动化测试的投入策略,但是初次接触测试金字塔的人对这个版本可能产生误解,以为测试金字塔只包含单元测试、服务测试和UI测试。

图2-3 测试金字塔(Mike Cohn版)

显然这三层的命名并非作者想表达的核心意思,因此大家应该忽略掉这三层测试具体的命名,而去洞察这个测试金字塔的本质。

笔者认为Google曾提到的一种分层方法会让大家更加容易理解测试金字塔的本质。如图2-4所示,测试按照集成的规模,被分为小型测试、中型测试、大型测试,有些项目在大型测试之上还包含超大型测试,这里的“大”和“小”对应的是系统中被测试系统的集成范围的大小,如单个类相对孤立,集成范围是单个方法里的代码或与其他类中方法交互的代码,而UI端到端测试显然是更大范围的集成。

图2-4 测试金字塔(Google版本)

无论测试类型是什么,我们需要记住的核心点只有两个:

1)需要编写多个层级的测试;

2)越往上层走,集成范围越大,需要编写的测试数量就越少。

如果依照Google这种以范围大小来进行测试分层的方式,测试金字塔就可以不局限在功能自动化测试领域,而扩大到整个功能测试领域。

大家需要理解测试金字塔的本质,这样才可以设计出属于自己团队实际情况的测试金字塔。

3. 敏捷测试中测什么与怎么测

回到测试策略需要解决的问题本身,在敏捷测试中我们需要关注测试什么以及怎么测试?

敏捷测试中测什么?这有两个方面需要重点考虑:一方面是敏捷中的迭代测试;另一方面是敏捷中的发布测试。

(1)迭代测试

根据故事在敏捷开发流程中的重要性,迭代测试的核心是故事测试,我们需要考虑测试以下几个部分。

1)测试故事中的验收条件(需求)本身。在故事卡开卡(kick off)阶段,测试人员与业务分析师一起讨论故事卡中的验收条件是否完备,以及是否存在隐性的非功能性需求。

2)测试实现故事的程序。开发人员通过单元测试、集成测试等较低层级的测试来保证代码内部逻辑的正确性,测试人员基于开发人员已有的测试,从较高层级,如接口、UI等测试来验证条件是否被正确实现。

3)测试故事的业务价值。测试人员、开发人员、业务分析师一起向客户进行演示,确保故事确实是客户想要的。

(2)发布测试

根据发布测试的长度与发布周期,分为两种流程。

图2-5所示的发布测试是系统经过很多次迭代后在发布版本前做的,图2-6则是一种较短周期内进行的发布测试,例如系统经过2次迭代(周期还可以更短)后在发布版本前做的发布测试的流程。

图2-5 敏捷中的迭代测试与发布测试(n次迭代后发布一次版本)

发布测试通常发生在发布版本前的一次迭代过程中,用于对系统做整体的功能验证和回归。发布测试包括了回归测试、用户验收测试(还有可能是Beta测试,这取决于我们定义谁是“用户”)以及系统级非功能性测试,如性能测试、安全测试、用户体验测试等。

图2-6 敏捷中的迭代测试与发布测试(2次迭代后发布一次版本)

敏捷中的发布测试与传统的发布测试很相似,但需要注意的是,在优秀的敏捷实践中,自动化测试会在每次迭代结束前开发完成,因此,敏捷中的回归测试实际上每天都在运行,在发布测试阶段,自动化的回归测试已经在前一天晚上执行完成。除了自动化回归测试外,通常还会引入Bug Bash,邀请整个产品团队中的其他角色进行1~2个小时的找Bug游戏。在加入大量的自动化回归测试后,敏捷中的发布测试周期可以被压缩到只有1~2天甚至几个小时,实现图2-6中的敏捷测试流程。

(3)敏捷测试中怎么测试?

首先,我们需要明确谁来测试。在敏捷中,测试是全团队的责任,敏捷更加需要T型人才,这与传统测试非常不同。基于团队中不同角色的技能优势,常见的分工如下。

1)测试人员是质量布道师,负责团队的测试用例设计、探索性测试执行、测试的赋能(如与开发人员结对实现BDD、帮助评审开发人员的单元测试及集成测试设计等)。

2)开发人员是自动化测试的主要实施者。

其次,对于故事的测试会考虑以下内容。

1)根据被测试程序的具体实现考虑如何测试。

2)测试金字塔则会重点给出测试类型的比例。

3)故事测试时可以采用Mock手段,在依赖组件测试未完成时,可以先完成故事卡的测试。

4)持续的非功能性测试:从需求规划阶段就要考虑非功能性需求,在故事卡阶段考虑是否实施对应的非功能测试,以及如何在系统未完全开发完时进行非功能性测试。

再次,对于发布测试执行策略我们怎么设计。

1)测试环境要贴近生产的集成环境。

2)对回归测试,我们需要考虑自动化测试+脚本类手工测试+一定量的探索性测试+Bug Bash。

3)对非功能性测试,我们需要在类生产环境中进行,甚至可以考虑在生产环境中进行。

最后,所有的自动化测试都应该在持续交付流水线上自动化运行,这样才能够保障测试的效果。