“测试策略”通俗来讲就是6个字:“测什么”和“怎么测”。
测试方针是产品测试中的通用要求、原则或底线。
测试方针举例:
试策略仅针对当前特定的产品版本而言,并不像测试方针那样具备通用性。反过来,我们倒是可以这样理解测试策略:循测试方针+项目实际情况=测试策略
试策略需要遵循测试方针,并不意味着我们不能根据项目的实际情况来对测试方针进行调整。
测试策略也不是测试计划,它们之间的关系是:通过测试策略确定的测试活动,在测试计划中被拆解为一个个任务,并为每个任务确定工期、执行的先后次序和责任人,如图1所示。
图1 测试策略与测试计划的关系
表1 “测试计划”示例
此外,测试计划的制订者是测试经理,属于测试管理的范畴。而测试策略的制定者是软件测试架构师,属于测试技术的范畴。
1)测试方案主要解决的是特性在测试设计和测试执行方面的问题
测试策略要解决的是产品测试的六大问题。显然,测试方案要解决的问题没有那么“高大上”,就是如何对特性进行测试设计和如何安排这个特性的测试执行,具体包括:
举例如下:
测试方案模板(以一个“特性”为单位):
2)测试方案需要遵循测试策略
测试方案需要遵循测试策略对具体某个特性的测试深度和广度的要求。
例如,某测试策略对特性A和特性B的测试说明,见表2。
表2 测试说明
可见,我们还是需要一套方法来指导我们制定测试策略的整个过程,“四步测试策略制定法”应运而生,如图2所示。
图2 四步测试策略制定法
1)我们的测试目标就是让产品在发布的时候能够满足事先约定的质量目标
2)围绕产品质量目标进行刚刚好的测试
3)将目标—行为—评估形成闭环
图3 产品质量评估
如图3:
1)提前识别项目中可能存在哪些会阻塞测试的风险,然后基于风险来调整测试策略
实际项目中真的有很多问题,都会让我们的测试变得举步维艰。
举例:实际项目中测试活动无法顺利开展的一些例子
“骨感”的现实告诉我们,需要提前识别项目中可能存在哪些会阻塞测试的风险,然后基于风险来调整我们的测试策略,增加一些测试活动或者质量保证活动。
2)基于风险来加强和降低测试投入
何时开展测试策略的制定活动?制定测试策略是一次到位,还是要分几次完成?
这就需要我们将测试策略的制定和研发流程结合起来。
1)测试策略的结构
图4是一个传统研发流程示意图。针对这个研发流程,我们设计了总体测试策略—阶段测试策略—测试执行策略这样的测试策略结构。
图6-4 传统研发流程示意图
有了这样的结构,我们能够将当前的测试策略总是控制在“当下”,即项目的情况总是在比较确定的范围内,避免我们过于纠结“未来”。
2)根据研发流程来安排测试活动
测试策略中具体的内容,也需要和研发流程保持一致,确保测试和开发的节奏能够彼此吻合。
从大层面来说,测试在各个阶段的活动和开发的活动是能够配合起来的,如图6-5所示:
图6-5 测试人员职责
要达到这个大层面的吻合,是比较容易的。相对比较困难的是,是在版本测试阶段,开发活动和测试活动彼此配合的问题。简单地说,就是开发人员在做计划的时候是否考虑了测试活动:
这就需要软件测试架构师能够做好版本测试策略,能够和开发人员进行有效沟通,使得双方能够理解彼此的节奏,达到更好的配合。
除此之外,我们即将要介绍的测试分层,也能帮助我们更好地制定版本测试策略。
到目前为止,我们已经能够综合考虑研发流程、风险,并基于产品质量目标来制定测试策略。通过上面的分析,我们可以得到很多测试活动,会发现有那么多要做的事情,现在的问题是我们该以什么策略去安排这些测试活动?
这个问题的最佳答案就是进行“测试分层”。
测试分层最大的价值在于:
通过前面的介绍,我们了解到在使用四步测试策略制定法来制定测试策略时,会使用到一些方式或者模型。总的来说,如图6-6所示。
图6 四步测试策略制定法中用到的方式或模型
产品质量评估模型将用在测试目标的确定和评估上,它是整个测试策略的基础。在介绍这个重要模型之前,我们想先花一点笔墨来讨论一下一个优秀的产品质量评估模型应该具备哪些特征。
产品质量评估中的几个场景:
结果:
我分析出现场景3中的问题,主要原因有3点:
例如,我们以测试的代码覆盖度要达到90%作为一项质量目标。为了达到这个目标,我们可能会选择一些容易进行测试“覆盖”,但实际上风险并不大的地方进行测试。虽然最终能达到90%的测试覆盖目标,但是没有被测试到的10%那部分情况如何,是否真的不需要测试,可能会有哪些风险,对我们来说都是“未知”的。未知正是心里没底的源头。
如果我们将这个问题从评估引申到目标的层面,如果我们在制订目标的时候,考虑的不仅仅是指标,而能包含一些如“对重要特性,要达到100%的测试覆盖”“测试方法要包含语句覆盖、判断覆盖、路径覆盖”等的描述,以此作为要达到的质量目标,不仅能解决上述的问题,还能更好地帮助我们确定要进行的测试活动。
综上,一个优秀的产品质量评估模型,应该具备如下特质:
我们将从3个方面来建立软件产品质量评估模型,对产品质量进行分析、确定和评估(图7):
图7 产品质量评估模型
表3 测试覆盖度评估的定义与属性
需求覆盖度的目标必须为100%,即测试保证对产品承诺要实现的需求都进行。
“需求覆盖度”中的“需求”,可以是“包需求”,也可以是“需求规格”“story”“user case”等可以代表项目中产品需求的内容,大家可以根据项目的实际情况来选择。
需求覆盖度评估有以下两种方法:
方法1:直接在需求表中确认测试情况
方法2:建立测试用例和需求的对应关系
方法2是在测试设计的时候,通过编号来建立需求和测试用例的对应关系。这样我们只要保证这些测试用例都被执行了,需求也就都被测试验证了,见表6-5。
方法2的优势是,测试能够从一开始就保证需求的覆盖,从源头上避免了需求遗漏的风险;还很容易通过不同的测试设计方法,让不同优先级的需求能够有不同的测试深度,更利于软件测试架构师对整个项目进行把控。
但是方法2也有一些需要注意的地方:
表6-6 路径分析法总结
第一步:确定路径覆盖策略。 软件测试架构师可以以特性或者功能为粒度,根据该功能的质量目标来确定路径覆盖策略。在如何选择确定路径覆盖策略上,建议如下:
表7 路径覆盖策略的记录
第二步:使用路径分析法设计测试用例。
第三步:跟踪测试用例的执行情况。
当测试团队按照路径覆盖策略完成了用例设计后,对路径覆盖度的评估,就转换为了测试用例执行情况的评估。我们的目标是这些设计的用例能够至少被执行一遍,并且测试结果为“通过”。如果存在测试用例在产品发布的时候都被“阻塞”,无法执行的情况,我们就需要对阻塞的情况进行分析,评估当前的覆盖度是否能够满足测试的基本要求。
1.测试用例执行率
2.测试用例执行通过率
3.测试用例和非测试用例发现缺陷比
们希望“通过测试用例发现的缺陷”和“发散测试”,也就是非测试用例发现的缺陷”的比值能够在一个合理的范围内。
如果比值过低,即大部分缺陷都是通过发散测试发现的,可能的问题是:
如果果比值过高,大多数缺陷都是通过测试用例发现的,可能的问题是:
图8 详细总结图
其中:
测试投入分析也是很重要的一项测试过程评估项目,在这里我们主要从测试人员安排和测试投入工作量来进行分析,确认重要的、高风险的特性能够保证测试投入,符合测试策略。
表8 测试投入分析
但是如果我们仅仅把缺陷当成产品问题的记录,而不去挖掘缺陷数据背后隐含的和产品质量有关的信息,就显得太可惜了。
缺陷密度是指每千行代码发现的缺陷数。我们在确定了缺陷密度后,还可以顺带得到缺陷总数。
对一个产品研发项目而言,确定、分析缺陷密度的重要意义在于:
我们能够在产品测试之前,较为准确地预测产品的缺陷密度并将此作为一个测试目标,主要基于如下假设:
如果我们发现实际的缺陷密度值偏高,通常最可能的原因为:产品整体质量不高。此时,软件测试架构师可以:
提高缺陷密度的预估值。
考虑和研发经理、开发人员、系统工程师等一起进行一些质量改进和质量保证工作,如加强评审等。
如果我们发现实际的缺陷密度值偏低,通常最可能的原因为:
在每个测试分层(如集成测试、系统测试)开始的时候确定缺陷修复率目标。有时候产品的缺陷实在太多,为了保证重要缺陷能够被优先修复,我们可以对缺陷按照严重程度进行划分,然后按照不同的严重程度来确定缺陷修复率。
1.缺陷的严重程度
表9 缺陷的严重程度的定义与示例
缺陷趋势是指“随着测试时间的进行,测试发现的缺陷趋势和开发解决缺陷的趋势”。我们进行此项分析的重要原因在于:缺陷趋势分析能够帮助我们判断当前系统是否还能很容易地发现缺陷,进而帮我们确定是否可以退出测试,发布产品。
6.3.1 绘制缺陷趋势图
表10 缺陷趋势分析表
我们将表10绘成图,就得到了如图9所示的缺陷趋势分析图。
图9 缺陷趋势分析图
在绘制缺陷趋势分析图时,不要忘记去掉节假日、周末公休日等“没有工作的日子”。
6.3.2 缺陷趋势曲线的“凹凸性”和“拐点”
1)理想的“累积发现的缺陷趋势”曲线
图10 理想的变化趋势
2)“累积发现的缺陷趋势”的“拐点”出现得过早
“拐点”的出现,意味着测试团队在这个测试阶段里已经无法有效发现产品的缺陷了。出现这种情况,可能的原因有:
3)“累积发现的缺陷趋势”的拐点未出现
这说明在这个测试阶段里,测试团队依然可以发现产品大量的问题。出现这种情况,可能的原因是:
出现第一种情况,这个团队的测试者水平应该比较不错(至少掌握的测试方法比较多);也应该比较有测试激情(不是按照软件测试架构师要求的任务测完就结束了,而是自己主动去发现系统更多的问题);另外版本的质量可能也不错(至少还能够使用各种测试方法来“折腾”系统),没有严重的测试阻塞。但这依然需要软件测试架构师和测试者仔细核对测试计划,确认测试者是在保证了测试计划的前提下才进行发挥的——核对的过程可能会让人感到有些尴尬,但我们的核心理念是:通过测试策略来进行“刚刚好”(我们必须保证对重点测试部分的确认)的测试,而不仅是为了发现产品的缺陷。
如果确认发现测试计划存在偏差,需要在下个版本中进行补充测试,并和测试者做好沟通。
出现第二种情况,软件测试架构师可以考虑从如下几个方面来更新后续的测试策略:
6.3.3 缺陷是否收敛
我们在判断缺陷趋势是否收敛时,需要具备以下两个条件,缺一不可:
当我们发现缺陷不收敛时,做好代码改动方面的控制,是一个很好的思路:
表11 缺陷年龄的定义
进行缺陷年龄分析,能够帮助我们确认每个可能引入缺陷环节、可能引入的缺陷是否都已经被有效去除。具体操作时,我们通过以下简单的3个步骤来开展缺陷年龄分析活动。
6.4.1 确定缺陷的缺陷年龄
如果你的项目有缺陷的管理工具(如bugzilla),可以增加缺陷年龄的选项。在开发修复缺陷的时候,可以对缺陷年龄进行选择。
如果没有缺陷管理工具也没有关系,你可以使用类似表6-12的形式来确定缺陷年龄。
表12 缺陷年龄确定方法
6.4.2 统计出各类缺陷年龄的数量,绘制缺陷年龄分析图
表13 缺陷年龄的数量
图11 缺陷年龄分析图
6.4.3 进行缺陷年龄分析
我们在进行缺陷年龄分析之前,需要先理解一下理想的缺陷年龄应该具有怎样的特点。
1)理想的缺陷年龄分析图
理想的缺陷年龄分析图应该是如下这样的。
(1)在缺陷的引入阶段就能及时发现该类缺陷,缺陷不会逃逸到下个阶段,如图12所示:
图12 引入阶段
如果真能达到这样的水平,测试也就可以“光荣”失业了。但实际情况是,每个阶段都会有一些缺陷“逃逸”到下一阶段,需要“测试”来发现这些逃掉的缺陷。
我们已经了解到测试不应该想到哪里就测到哪里,而应该进行分层测试:在每个测试分层围绕不同的测试目标,使用不同的测试方法来进行测试。
(2)在特定的测试分层发现该层的问题,如图13所示。
图13 发现特定测试分层问题
对其他几类缺陷年龄,我们的期望是:
2)没有在特定的测试层次发现该层的缺陷
例如,在集成测试阶段,我们希望发现在编码阶段和设计阶段引入的缺陷,但实际上却发现了大量的在需求阶段引入的缺陷。这说明:
这就需要测试或整个研发团队来有针对性地进行改进。例如:
3)继承或历史遗留引入的缺陷过多
当我们发现测试中出现了很多因为继承或历史遗留引入的缺陷时,这就说明产品还存在一些“旧账”尚未清理,这时我们需要:
图14清理“旧账”
4)新需求或变更引入的缺陷过多
5)缺陷修改引入的缺陷过多
缺陷的触发因素就是测试者发现缺陷的测试方法。缺陷触发因素分析,就是对测试中使用的测试方法进行分析。
对缺陷触发因素进行分析,能够帮助我们确认产品测试是否已经进行得足够全面和深入
和缺陷年龄分析方法类似,我们也可以通过下面3个步骤来进行缺陷触发因素分析。
6.5.1 确定缺陷的测试方法和测试类型
果没有缺陷管理工具也没有关系,你可以使用类似表6-14的形式,来确定该缺陷的测试方法和测试类型。
表14 确定缺陷测试方法和测试类型
6.5.2 统计出各种测试方法发现的缺陷数目,绘制缺陷触发因素分析图
图15 缺陷触发因素分析图
6.5.3 进行缺陷触发因素分析
在理想情况下,我们希望做出的缺陷触发因素图和测试策略是吻合的。例如,当前版本我们的测试策略是:
对功能首先进行配置的遍历测试,需要保证新提交的命令行和以前已有的Web页面功能具有一致性;再进行基本功能测试,能够覆盖业务流程的基本路径;最后进行满规格的测试。
如果我们持续对产品进行缺陷触发因素分析,参考历史数据,结合自身的经验,我们还可以得到“不同的测试方法发现缺陷的大致比值和分布”。当然,这个比值可能不是很准,但是也可以作为软件测试架构师对数据进行分析时的参考。
表15 产品质量评估表
我们将风险分析技术用在保证测试策略的顺利进行和基于风险来加强或降低测试投入上,涉及的主要技术为风险识别、风险评估、风险应对和老功能分析。
此处我们讨论的风险分析的对象是测试策略,目标是提前识别那些可能会阻塞测试策略顺利进行的问题,包括风险识别和风险评估两个部分。
7.1.1.风险识别
图16 风险识别的方法
举例:对测试设计进行风险识别
Step2:分析上述内容都能够保质保量顺利地进行,需要哪些条件。例如:
Step3:逐一分析这些条件是否能够满足。假如条件1和条件4可能无法满足,那么识别出来的风险点就是:
需要特别说明的是,虽然此处我们进行风险分析的对象是测试策略,围绕测试活动能否正常展开,但并不等于我们只在测试内部识别风险点——我们依然要从整个项目的角度来进行风险识别。我们可以使用表6-16风险识别清单,来帮助我们进行风险识别。
表16 风险识别清单
7.1.2 风险评估
风险评估的目标就是确定风险优先级。
1)风险优先级正交表
表17 风险优先级正交表
表18 常见风险及应对思路
7.3.1 差异性分析
差异性分析是指找出老功能在新版本和老版本上的差异。这些差异包括需求、设计、平台、实现等各种差异。
7.3.2 历史测试情况分析
历史测试情况分析是对老功能在老版本中的测试情况(包括测试策略、测试用例、缺陷)进行分析,以此来确定老功能在新版本中需要采用怎样的测试策略。
1)确认老功能在新版本和老版本中的质量要求是否一致
2)进行测试方法分析
表19 分析角度
3)进行缺陷分析
表20 老功能历史缺陷分析点
4)对“组织和人”进行分析
表21 测试团队分析
我们将分层测试运用在测试目标的SMART化上和测试活动的安排上。
对V模型而言,每个测试分层测试图测试的重点为:
1.某通信公司的测试分层
图17 某通信公司的测试分层
和V模型相比,集成测试在本例中被分成了MST和BBIT;系统测试被分成了SDV、SIT和SVT。
为什么此处的“测试分层”要这么复杂呢?这是因为在这个例子中,被测对象是通信产品。我们知道,通信产品需要包含硬件、驱动和软件,业务也比较复杂,还会涉及很多协议和规范。在设计上常常会包含多个子系统,涉及很多接口。用户不仅关注功能,还特别关注可靠性、性能等方面的质量,对产品质量整体要求很高。
2.某公司在敏捷环境下的测试分层
图18 某公司在敏捷环境下的测试分层
和前面的介绍的测试分层相比,本例就显得简单多了:
这时被测对象是一个纯软件产品,根据用户的业务需求进行迭代开发,但总体来说并不复杂,基本不涉及协议或规范。用户比较关注功能、易用性和性能,对可靠性方面的问题有一定的容忍性,总的来说对质量的整体要求并不算太高,希望产品能够快速交付。
在这样的背景下,快速评估产品是否能够发布,进行快速测试是有必要的。如果我们还是按照V模型中的测试分层来进行测试,就显得太重了。在这个测试分层中,我们在单元测试层中测试代码、接口的质量;提交给测试后,在功能测试层中集中测试功能;待功能相对稳定后,在非功能测试层中再集中易用性、性能和可靠性等方面的内容;在探索测试层,再结合缺陷,进行补充测试和回归测试。