测试架构师:3 软件测试架构师的知识能力模型(一)

测试架构师:3 软件测试架构师的知识能力模型(一)

2016-08-15

 

测试架构师从事的并不是一项纯测试技术的工作,而是一门需要结合产品、沟通协调、书面表达等综合性的艺术,如图1所示。

 

图1 软件测试架构师需具备的能力

从测试技术来说,软件测试架构师需具备的测试技术能力:

  • 软件产品质量模型
  • 测试类型
  • 测试方法
  • 探索式测试
  • 自动化测试

目录

1 软件产品质量六属性
  1.1 功能性
  1.2 可靠性
  1.3 可移植性
2 测试类型
3 测试方法
  3.1 产品测试车轮图
  3.2 功能测试方法
    3.2.1 单运行正常值输入法
    3.2.2 单运行边界值输入法
    3.2.3 多运行顺序执行法
    3.2.4 多运行相互作用法
  3.3 可靠性测试方法
    3.3.1 异常值输入法
    3.3.2 故障植入法
    3.3.3 稳定性测试法
    3.3.4 压力测试法
    3.3.5 恢复测试法
  3.4 性能测试方法
  3.5 易用性测试法
    3.5.1 一致性测试法
    3.5.2 可用性测试法
4 测试设计技术
  4.1 测试点不等于测试用例
  4.2 四步测试设计法

1 软件产品质量六属性


 返回

图2 软件产品质量六属性

1.1 功能性

表1 功能性子属性

  • 适合性:对Windows的计算器来说,软件产品为用户提供的所有和“计算”相关的功能,就是适合性。
  • 准确性:对Windows的计算器来说,计算器本身计算结果的正确性是计算器软件在准确性方面的一个表现
  • 互操作性:对Windows的计算器来说,计算器中不同功能、特性之间是否能够正确地相互配合是计算器在互操作性方面的一个表现;此外,对不同操作系统的支持,如对Windows 7不同版本(包括不同的补丁版本)的支持,对不同工作模式(如安全模式、带网络连接的安全模式)的支持也是互操作性的体现。
  • 安全性:对Windows的计算器来说,计算器不应该包含能够被利用的安全漏洞和与“用户权限”相关的内容,如“管理员和访客都应该有相同的使用权限”等。
  • 功能顺从性:对Windows的计算器来说,功能顺从性可以理解为,作为一款计算器,计算规则(如平方运算、统计运算等)要和数学中的相关规则保持一致。

1.2 可靠性

下面3个层层递进的句子,可以帮助我们来理解用户可靠性方面的要求:

  • 第一层:设备最好不要出故障;
  • 第二层:设备出现故障了不要影响主要的功能和业务;
  • 第三层:如果影响了主要功能和业务,系统可以尽快定位并恢复。

表2 可靠性子属性

  • 成熟性:对Windows的计算器来说,成熟性可以理解为产品的功能失效的概率。例如,计算器在持续运行一段时间后,就会出现计算方面错误。一般来说,这种错误都可以通过重启软件、重启设备等方法恢复。
  • 容错性:对Windows的计算器来说,容错性可以理解为产品对用户“错误输入”的处理应对能力
  • 可恢复性:对Windows的计算器来说,可恢复性可以理解为计算器一旦出现了产品自身无法预期的异常(如无响应、重启)后,能够恢复。
  • 可靠性顺从性:对Windows的计算器来说,在可靠性顺从性方面并没有严格明确的标准,但是也会有一些潜在的约定,如计算器需要能够识别出所有数学运算的异常输入,并给出错误原因的提示。通信类产品在可靠性顺从性方面就有比较严格的标准,如系统的故障率不能高于多少、故障恢复时间不能长于多少等。

1.3 可移植性

  • 适应性:对Windows的计算器来说,适应性可以理解为,计算器在不同大小的显示屏中,计算器的布局、大小、清晰度、按键的排列等是否都能正常地显示。
  • 可安装性:对Windows的计算器来说,可安装性可以理解为,计算器能否被顺利安装到不同的Windows操作系统上,并能正常运行。
  • 共存性:对Windows的计算器来说,共存性可以理解为,计算器和其他软件能够同时在Windows中共存,不会存在资源(如CPU、内存等)争抢方面的问题。
  • 易替换性:对Windows的计算器来说,易替换性可以理解为,假设产品开发了新的计算器,新的计算器能够成功替换掉老的计算器。(注意,此时不是指通过“产品升级”的方式,而是可能存在“新”“旧”两个计算器同时共存的情况。)
  • 可移植性的依从性:对Windows的计算器来说,可移植性的依从性可以理解为Windows产品在可移植性方面的一些约定。例如,计算器并不是针对某款特定的操作系统开发的,需要支持Windows所有操作系统。

2 测试类型


 返回

测试类型指的是测试需要考虑的不同角度。我们可以借助软件产品质量模型(以下简称“质量模型”)来快速定义、理解测试类型。

图3 质量属性和测试类型的关系

表5 常见测试类型及其与质量属性关系表

3 测试方法


 返回

3.1 产品测试车轮图

测试类型,即测试要从哪些角度去测试产品,确定了测试的思路。接下来我们要讨论的就是怎么做的问题了,即具体的测试方法。

图4 产品测试车轮图

图4 描绘的质量属性的六大类和测试类型之间的关系,并没有深入到各个质量子属性和各个子属性对应的测试类型中去(大家不妨自己动手绘制一下“质量子属性”的车轮图)。

从“车轮图”中能够分析出产品测试的两个关键问题:

  • 一是如何保证测试验证的“全面性”的问题。显然,只要我们使用的测试方法能够覆盖六大质量属性,我们的测试就不会出现大方向性的遗漏。
  • 二是如何确定测试“深度”的问题。一般来说,测试团队使用的测试方法越多,对产品就测试得越深。

这些都会影响测试的效果,影响测试对产品质量的评估。除此之外,“车轮图”还能帮助我们评估测试团队的能力。软件测试人员能够驾驭的测试方法越多,他的测试能力就越强。

3.2 功能测试方法


 返回

功能测试方法有:

  • 单运行正常值输入法。
  • 单运行边界值输入法。
  • 多运行顺序执行法。
  • 多运行相互作用法。

定义:

  • 运行:在软件测试中,测试人员模拟的用户的“操作”或“行为”。
  • 单运行:在软件测试中,测试人员模拟的用户的“一个操作”或“一个行为”。
  • 多运行:在软件测试中,测试人员模拟的用户的“多个操作”或“多个行为”。

也就是说,“运行”是指从用户的角度来看,有意义的操作或行为。从功能的层面来说,一个“运行”确定了“输入”和“输出”的一种可能的情况,如图5所示。

图5 功能层面的运行示意图

有时候,我们会从设计的角度来划分功能,不能为用户提供一个完整的、有意义的行为,例如“用户和邮件服务器建立了一个新的连接”“邮件服务器删掉了和用户的连接”,这种细粒度的功能即使确定了输入和输出,都不算作“运行”。这时,可以将多个功能组合起来,直到这个功能能够为用户提供完整的、有意义的行为为止,如图6所示。

图6 功能与运行的关系

3.2.1单运行正常值输入法  

就是测试时输入的“A1”和“A2”是系统允许的“正常值”的测试方法。

3.2.2单运行边界值输入法

就是测试时输入的“A1”和“A2”是系统的“边界值”的测试方法。

3.2.3多运行顺序执行法

将多个“单运行”操作放在一起考虑,得到的结果就是“多运行”操作。使用多运行顺序执行法进行测试时,分析各个运行之间的顺序性,是使用该方法的关键。

  • 多运行顺序执行法在和用户的操作习惯相关的地方使用非常有效。
  • 此外,多运行顺序执行法也比较适合使用在功能的配置测试上。

表6 多运行顺序场景

序号 多运行场景 有关联性 多运行顺序
1 用户先发送一封电子邮件后,再收到一封电子邮件
2 用户收到一封电子邮件后,再接着发送这封收到的电子邮件
3 用户收到一封电子邮件后,再发送一封任意电子邮件

3.2.4多运行相互作用法

多运行相互作用法是指在功能测试时把多个存在相互关系的运行组合在一起进行测试的方法,如图7

图7 多运行相互作用法

和多运行顺序执行法强调多个运行之间的顺序性不同,多运行相互作用法强调的是多个运行之间的关系性,这个关系可以是外在关系,如某个业务的顺利进行需要多个运行之间相互协作;也可以是内在关系,如这些运行会用相同的资源(如内存或其他硬件资源)。

需要特别指出的是,都是“针对一个用户”的操作场景,而不是“两个不同的用户同时发送邮件”或是“一个用户发送邮件,一个用户接收邮件”这样的场景。事实上,前者属于功能测试的范畴,而后者属于可靠性测试的范畴。

3.3 可靠性测试方法

3.3.1 异常值输入法

异常值输入法是一种使用系统不允许用户输入的数值(即异常值)作为测试输入的可靠性测试方法。

3.3.2 故障植入法

故障植入法是把系统放在有问题的环境中进行测试的一种可靠性测试法,主要能够测试到的质量属性是容错性和成熟性。
和异常值输入法不同,异常值输入法是直接输入一个系统认为是错误的、不支持的值;而故障植入法是把系统放在有问题的环境中,但是输入依然是正常值。

  1. 用户的业务环境中,会有哪些故障、错误或问题?列出这些场景,把系统放到这些场景中,运行正常的业务,分析此时系统的反应是否合理。
  2. 如果系统被部署在用户的硬件环境中,考虑系统所需要的硬件资源,如CPU、内存、存储空间等,在出现不足的情况下,系统的反应是否合理。还是以“用户发送电子邮件”为例。网络故障对用户来说是一个常见的故障,如断网,网络时断时续、存在丢包。
  3. 果系统被安装在用户的系统中,考虑系统在软件冲突、驱动不正确等情况下,系统的反应是否合理。
  4. 如果系统是一个独立的设备,考虑它的关键器件(如机框、单板、插卡、硬盘、芯片等)出现问题时,系统的反应是否合理。

3.3.3 稳定性测试法

稳定性测试法是在一段时间里,长时间大容量运行某种业务的一种可靠性测试法,它能够非常有效地测试到系统的“成熟性”,是非常重要的一种可靠性测试法。

需要特别指出的是,稳定性测试法、压力测试法和性能测试法是存在一定关系的,这个关系纽带就是产品规格。

产品规格:产品承诺的能够处理的最大容量或能力。例如,系统最多支持100个用户并发登录、系统最多支持建立100条安全策略都是产品规格。

  • 性能测试的目的就是测试产品真实规格是否和说明书中承诺的需求规格一致。显然,最后我们实测出来的性能值,就是系统真正能够处理的最大容量或者能力。
  • 稳定性测试是在低于性能值的前提下测试的。事实上,用户在使用系统时,也不会时时刻刻让系统在极限的状态运行,在测试时,我们可以控制测试中的负载量,使其和用户的实际使用情况尽量接近,使得测试能够更为准确,更有价值。
  • 压力测试是在高于性能值的前提下进行测试的。虽然测试时负载超过了系统能够处理的最大能力,但并不等于在这种情况下系统的功能都会失效,我们需要根据实际情况来分析系统的表现是否合理。例如,系统最多支持100个用户并发登录,但此时有110个用户同时发起了登录的操作,那么系统应该保证这110个用户中有100个用户能够正常登录,有10个用户不能登录才合理,而不是所有用户都不能登录。

现在让我们再回到本节的主题——稳定性测试上(性能测试法、压力测试法将在后文中陆续为大家介绍)。从方法的角度来说,稳定性测试法是所有测试方法中最为有趣的,可以总结为一个“四字诀”——多、并、复、异。

  • “多字诀”的要义是,在测试中通过增加用户对功能的操作数量,来测试系统的稳定性。
  • “并字诀”的要义是,在测试中让多个用户同时来操作这个功能,由此来测试系统是否依然稳定。有时我们也称这个测试为并发测试。
  • “复字诀”的要义是,在测试中让一个或多个用户,反复进行新建、刷新、删除、同步、备份之类的操作,以此来测试系统是否稳定。
  • “异字诀”的要义是,在测试中让一个或者多个用户,反复进行异常操作,验证系统是否能够持续做出合理的反应。与异常输入法和故障植入法相比,“异字诀”强调的是“持续”和“累积”。事实上,使用“异字诀”来测试往往还比较有效,这是因为,开发在编码的时候,容易考虑正确情况下资源的申请和回收,忽视异常情况下资源的回收。

3.3.4 压力测试法

压力测试法是在一段时间内持续使用超过系统规格的负载进行测试的一种可靠性测试方法。

尽管产品已经声明了规格,只承诺在规格范围内才能提供稳定可靠的功能,不承诺在超过系统规格的情况下还能提供正确的功能,但压力测试仍然是有意义的。一个重要的原因是,业务的突发现象——用户的业务负载并不是平均的,可能在极短的时间里,出现超过负载的情况,但是平均下来,却没有超过规格,如图9所示。

图8 业务的突发现象

我们希望系统在突发的情况下不会像纸牌屋那样脆弱,而是有切实的应对措施,如不处理超过系统规格的负载、记录日志供用户分析突发原因等。不会因为突发情况导致死机、反复重启等致命问题,这才是我们进行压力测试的真正目的。为了达到这个测试目标,我们在进行压力测试时,需要使用突发形态的负载模型,如图9

图9 突发形态的负载模型

不建议用持续超过系统规格负载这样的测试方法来挖掘产品的问题。但是对测试来说,使用持续超过规格的负载模型测试也并不是完全没有意义,它是我们另外一种可靠性测试法——恢复测试法的组成部分

3.3.5 恢复测试法

恢复测试法是指使用持续超过规格的负载进行了测试后,再将负载降到规格以内的测试方法,如图10

图10 恢复测试法

持续进行超过规格的负载测试时,允许规格内的业务不是100%正确。当负载降到规格值之内后,业务必须能够恢复到100%的正确。

为了加深大家对压力测试法和恢复测试法的理解,我们不妨来对比一下两个模型在不同负载下对“业务”结果的期望,如图11所示。

图11 突发负载模式和持续负载模式对业务结果的期望

可见,两个测试方法最大的差别,在于图中“黑色”的部分。在使用突发负载模式进行压力测试时,图中的黑色部分是不允许出现业务失败的,而使用持续负载模式进行恢复测试时,黑色部分允许出现业务失败。

3.4 性能测试方法

性能测试的目的是测试产品真实规格是否和说明书中承诺的需求规格一致,我们实测出来的性能值,就是系统真正能够处理的最大容量或者能力。

一般来说,产品的需求规格会给出性能期望值,测试者只需要确认产品能否达到规格即可。假如需求规格中对产品性能规格定义得很简单、很粗糙,我们可以按图12进行性能测试

图12 测试流程

第一步 测试出系统最好的性能值

在进行性能测试时,我们可以先试着测试出系统最好的性能值。我们可以以性能规格中要求的性能值作为测试的项目,测试出这些指标在系统中的极限。
不同产品的性能规格可能会千差万别,但总的来说,却可以分为以下两类。
1)系统能够正确处理新业务的最大能力

系统能够正确处理新业务的最大能力,我们也称为“新建”。例如,系统每秒能够允许多少新用户上线登录、系统每秒能够主动发起多少新的连接等。

针对系统的新建能力进行性能测试,测试的是系统为一个新业务从分配资源到完成处理流程的速度。业务处理流程和资源的总量都会影响系统的新建能力。需要注意的是,系统不能只“建”不“拆”:已经完成或异常的业务需要被及时拆除,占用的资源要能够被回收,用于新的业务。

2)系统能够同时正确处理的最大业务能力
系统能够同时正确处理的最大业务能力,我们也称为“并发”。例如,系统能够支持的最大用户同时在线数、系统能够同时发起的最大连接数等。

需要特别指出的是,“新建”和“并发”之间是存在关系的,如图13所示。

图13 新建和并发测试情况

注意:新建和并发这两个指标会互相影响,比如最大并发能力是4000,测试的时候只“建”不“拆”,当每秒新建150条,到24秒时,并行数大于最大并发能力是4000,而导致新建数降低。

因此,我们在测试系统最好的性能值时,需要注意测试指标之间的内在关系,在测试一个指标的时候,别的指标不能对这个指标造成影响。

第二步 分析会影响性能值的各种因素,测试它们对性能的影响

配置”和“业务”都会对性能指标产生影响。试想一下,配置了1条用户策略和配置了1000条用户策略的性能应该是不同的;系统接收1字节大小的邮件和接收10M大小的邮件测试出来的性能值也是不同的。在这个步骤中,我们要分析出系统中的哪些因素对性能有影响(性能下降),然后进行测试,分析性能下降是否符合预期,最坏的情况是否还算合理。

表7 在样本点能够正确处理的最大邮件数

表8 在不同过滤策略下能够正确处理的最大邮件数

通过测试这些性能值,我们很容易得到:

  • 哪些因素对系统性能的影响大,哪些因素对系统性能的影响不大。
  • 各个因素对性能的影响趋势。通过挑选测试的样本,通过数学中的“曲线拟合”技术,得到因素的影响曲线,我们可以通过曲线来分析这个下降趋势是否合理。
  • 在各个因素下,性能的最坏值。分析这个最坏值是否合理,是否会成为系统的性能“瓶颈”。

很多时候,影响一个性能指标的因素并不是单一的,而可能会有多个。在这个步骤中仅测试单个因素对性能的影响即可,多个因素对性能的影响可以放在典型场景中,选择典型的配置和业务来进行性能测试。

第三步 以场景为单位来测试性能

最后我们以“场景”为单位,来测试这个场景中的典型配置、典型业务下的性能值。

以“用户发送邮件”为例,假设在这个场景下,典型的配置为“200条过滤策略”,邮件大小为1KB、10KB、2MB以1:2:1混合情况下,邮件系统每秒能够接收并正确处理的最大邮件数。

3.5 易用性测试法

3.5.1 一致性测试法

一致性测试法在测试中关注的是产品的用户界面:

  • 风格、布局、元素上是否一致、统一。
  • 布局的合理性、操作的合理性、提示等是否符合UI设计规范。

一致性测试法能够测试到产品在易理解和易用性依从性方面的能力,但它并不关心产品功能是否正确,所以可以直接对产品的UI设计原型进行测试

3.5.2 可用性测试法

可用性测试法的测试对象也是用户界面,但在可用性测试中,我们关注的是产品提供的功能,对用户来说是否易于学习理解、易于使用,所以可用性测试需要和功能测试结合起来,以场景作为测试粒度,以用户的视角进行测试。

表9 可用性测试的关注点和标准

4 测试设计技术


 返回

表9 “用户发送电子邮件”的测试点

4.1 测试点不等于测试用例

如果我们拿测试点来进行测试,会发现很多让我们不爽、困惑的问题:

  • 问题1:这些测试点在内容上有重复,存在冗余。

  例如,测试点1、测试点4都会测试到“正确发送邮件”。

  • 问题2:一些测试点的测试输入不明确,不知道测试时要测试哪些。

  例如,测试测试点1时,我们并不知道我们要测试哪些“正常的输入数据”。存在类似问题的还有测试点5。

  • 问题3:总是在搭相似的环境,做类似的操作。

  有些测试点之间存在一定的执行顺序,需要把这些测试点放在一起测试。例如,先执行测试点6,再紧接着执行测试点11,可以最大限度地利用之前的测试环境和测试结果。

  • 问题4:测试点描述得太粗,不知道是不是测对了。

  有些测试点写得很粗,我们不知道测试目标是什么,或是该关注哪些地方。例如,测试点4,我们不知道将“用户发送电子邮件”和“用户接收的电子邮件”这两个操作放在一起,它们的“交互点”在哪里?

4.2 四步测试设计法

把测试点加工为测试用例,就叫测试设计,在这个过程中使用的方法就叫测试设计方法。路径分析法、判定表、正交分析法、等价类、边界值等都是常见的测试设计方法。

在测试分析中,我们对被测对象按照测试方法进行思考,就能得到测试点,所以测试分析是一个“发现性”的过程,如图14所示,而测试设计不同。

图14 测试分析是一个“发现性”的过程

大家可以做这样一个试验,让两个测试者根据“车轮图”来分析同一个测试对象,他们得到的测试点差异并不会太大,但是最后生成的测试用例却会千差万别。这是因为,从测试点到测试设计,我们会加工测试点,对它们进行组合、拆分,选择测试数据,等等,这是个“创造性”的过程。

图15 四步测试设计法的四个关键步骤

第一步:建模

其实,在这个步骤中,我们并不是要大家对每个测试点都原创出一些测试模型,而是根据测试点的特征,为测试点选择一个适合后续测试设计的模型。也许我们称这个步骤为“选模”更为贴切。

既然“选模”需要参考测试点的特征,研究测试点、分析特征的情况并对其进行归类是必不可少的。目前我们将其分为四类:

  • 类型1:“流程”;
  • 类型2:“参数”;
  • 类型3:“数据”;
  • 类型4:“组合”。

对每一类测试点,我们都给出了一些最适合的“建模”方法:

  • 对“流程”类,可以通过绘制“流程图”来建立测试模型。
  • 对“参数”类,可以通过“输入输出表”来建立测试模型。
  • 对“数据”类,可以通过“等价类分析表”来建立测试模型。
  • 对“组合”类,可以通过“因子表”来建立测试模型。

第二步:设计基础测试用例。

在这个步骤中,我们会对已经建立好的测试模型,来设计一些基础测试用例,覆盖这个测试模型。

测试用例和基础测试用例最大的差别在于,测试用例确定了测试条件(类似“在××情况下,进行××的测试”的描述)和测试数据(就是输入的“参数值”或“数值”),而基础测试用例只确定了测试条件。

第三步:补充测试数据。

在这个步骤中,我们为基础测试用例来确定测试输入,补充测试数据,这时基础测试用例就升级成真正的测试用例了。

第四步:扩展。

模型不是银弹,不能解决测试设计的所有问题。我们还需要根据经验,特别是对系统哪些地方容易发生缺陷的认识,补充一些测试用例,增加系统的有效性。

对测试点进行分类

在使用四步测试方法之前,我们首先要对测试点进行分类。分类的依据,就是看测试点是否有“流程”类的特征、“参数”类的特征、“数据”类的特征、“组合”类的特征。

 

posted @ 2016-08-17 18:29  明-Ming  阅读(5814)  评论(0编辑  收藏  举报