测试方法
before
在之前的部分,简单的介绍了关于测试方法都有哪些分类。
本小节主要来再深入的学习白盒、黑盒测试;静态和动态测试;人工、自动化测试,以及它们是如何划分的。
测试方法的划分
一般的,从看不看代码来划分黑、白盒测试。看代码和内部接口称为白盒测试,否则是黑盒测试方法。
而从软件是否运行的角度来划分静态和动态测试。不运行代码是静态测试,反之就是动态测试。
那么从我们人来参与的角度来看人工测试和自动化测试的。
黑、白、灰盒测试
刚才说了,我们从看不看代码来划分黑、白盒测试。
那黑盒测试可以有静态测试和动态测试,也可以有人工测试和自动化测试。
当然,白盒测试也是一样的。
比如我们要测这个自动售货机。
我们投币然后得到饮料;或者刷卡、扫码等都能得到想要的饮料。
我们做黑盒测试就是测试投币相关的逻辑、选择饮料相关的逻辑,找零或其他的逻辑。
这是我们不管内部结构,只是根据一些数据测试输入输出,比如投币5毛钱,却能得到一瓶2.5的饮料,这就是bug了。
等等等.....
除此之外,我们还需要看内部代码的逻辑,比如如何处理银行和第三方支付的接口逻辑,本地的饮料存储、统计等,看看相关关联的数据之间的交互。这些都是白盒测试范畴。
在测试之前,我们要搞清楚被测对象应该是什么样的,然后实际做出来的和预期进行比较,这样就能及时的发现缺陷;根据被测对象不同,而采用不同的测试方法。
白盒测试
白盒测试是依据被测软件分析程序内部构造,并根据内部构造设计用例,来对内部控制流程进行测试,可完全不顾程序的整体功能实现情况。
白盒测试是基于程序结构的逻辑驱动测试。
白盒测试又可以被称为玻璃盒测试、透明盒测试、开放盒测试、结构化测试、逻辑驱动测试。
白盒测试一般在测试前期进行,通过达到一定的逻辑覆盖率指标,使得软件内部逻辑控制结构上的问题能基本得到解决。
白盒测试能保证内部逻辑结构能达到一定的覆盖程度,能够给予软件代码质量更大的保证。
白盒测试发现问题后解决问题的成本较低,毕竟介入的早嘛。
白盒测试一般会用到静态分析和动态分析两类技术,常用的有:
- 静态分析:控制流分析、数据流分析、信息流分析;
- 动态分析:逻辑覆盖测试(分支测试、路径测试等)、程序插桩等。
逻辑覆盖率测试
根据覆盖的对象不同,存在多种逻辑覆盖测试:
- 语句覆盖;
- 判定覆盖;
- 条件覆盖;
- 判定-条件覆盖;
- 路径覆盖;
- ......
关于覆盖率的介绍,后续我们再聊。
逻辑覆盖率的统计是通过程序插桩来实现的。
程序插桩
程序插桩,最早是由J.C. Huang 教授提出的,它是在保证被测程序原有逻辑完整性的基础上在程序中插入一些探针(又称为“探测仪”,本质上就是进行信息采集的代码段,可以是赋值语句或采集覆盖信息的函数调用),通过探针的执行并抛出程序运行的特征数据,通过对这些数据的分析,可以获得程序的控制流和数据流信息,进而得到逻辑覆盖等动态信息,从而实现测试目的的方法。
简单来说,程序插桩就是我们在调试程序时,常常要在程序中插入一些打印语句(想想我们在程序中常用的print语句),其目的是希望在程序执行中打印出我们最为关心的信息,然后进一步通过这些信息了解程序执行过程中程序的一些动态特性。
从这一思想发展出程序插桩技术能够按照用户的要求,获取程序的各种信息,成为测试工作的有效测试手段。
我们往往通过借助被测程序中插入一些操作来实现测试目的的方法。
白盒测试的特点
- 测试人员需要了解软件的实现;
- 可以检测代码中的每一条分支和路径;
- 揭示隐藏在代码代码中的错误;
- 对代码的测试相对彻底;
- 实现代码结构上的优化;
- 白盒测试的投入较大,成本高;
- 白盒测试不验证(需求)规格的正确性;
综上所述,白盒测试对测试人员的要求要高!
黑盒测试
黑盒测试把被测对象看成一个黑匣子,只考虑期整体的特性,不考虑期内部具体实现。
黑盒测试的被测对象可以是一个系统、一个子系统、一模块、子模块、一个函数等。
黑盒测试又可以被称为基于规格的测试。
常见的黑盒测试类型
功能性测试:
- 一种是顺序测试每个程序特性或功能;
- 另一种是一个模块一个模块的测试,即每个功能在其最先调用的地方被测试;
容量测试,检测软件在处理海量数据时的局限性,能发现系统效率方面的问题。
负载测试,检测系统在短时间内处理巨大的数据量或执行许多功能调用上的能力。
恢复性测试,主要保证系统在崩溃后能回复外部数据的能力。
黑盒测试类型和质量模型
黑盒测试类型都来源于质量模型。
将软件的特性和质量特性结合起来就得到了测试类型。
一个软件特性可以和一个质量特性结合得到一个测试类型。
一个软件特性可以和多个不同的质量特性结合得到多个不同的测试类型。
容量负载测试所测试软件质量特性
黑盒测试的测试方法
常见的黑色测试方法有:
- 等价类划分法。
- 边界值分析法。
- 因果图分析法。
- 判定表法。
- 状态迁移法。
- 输入域。
- 输出域。
- 错误猜测法。
当然,无论是采用什么测试方法,目的都是为了减少测试时的测试用例数,都是为了用较少的测试用例发现更多的问题。
灰盒测试
根据利用的被测对象的信息不同,会采用不同的方法进行测试,一般的:
- 利用被测对象的整体特性信息,采用黑盒测试方法。
- 利用被测对象的内部具体实现信息,采用白盒测试方法。
- 如果既是利用被测对象的整体特性信息,又利用被测对象的内部具体实现信息,采用的就是灰盒测试方法。两种信息占比不同,相应的灰度就不同,完全是整体特性信息,就是黑盒测试,完全是内部具体实现信息,就是白盒测试。
黑、白、灰盒测试方法总结
我们一般从以下五个维度来区分:
- 测试阶段不同:
- 单元测试阶段主要利用白盒测试方法。
- 集成测试阶段主要利用灰盒测试方法。
- 系统测试阶段主要利用黑盒测试方法。
- 测试依据,因为测试阶段的不同,采用的测试方法也不同,那它们的测试依据也不同:
- 白盒测试主要依据详细测试说明书(LLD)。
- 黑盒测试主要依据需求设计说明书(SRS)。
- 灰盒测试主要依据概要设计说明书(HLD)。
- 测试方法:
- 白盒测试方法可以有静态和动态,控制流、信息流、数据流、各种覆盖率、插桩处理。
- 黑盒测试方法有各种测试类型(功能型、负载、恢复性),以及应用等价类、边界值、流程图法、正交法等。
- 灰盒测试这里即用白盒的,也用黑盒的。
- 评估基准:
- 白盒根据逻辑覆盖率来评估。
- 黑盒主要看需求规格的覆盖率。
- 灰盒主要看接口覆盖率。
- 特点不一样:
- 白盒测试,特点是及早的发现问题,定位问题也很快,缺点是对接口、对设计、程序之间的调用、用户感受也不是很好。
- 黑盒解决问题的代价比较大,很大发现模块内部的问题。
静态、动态测试
软件研发可以看成是一个生产过程,在此过程中会有产品输出或者称为工件输出。
输出的产品可以分为两类:
- 最终产品,如变编译后的软件、用户手册等。
- 中间产品,如SRS、HLD、LLD、源代码等。
无论是最终产品还是中间产品,都可以分成代码和文档。
文档进一步细分还可以分为:
- 开发文档,如SRS、HLD、LLD。
- 测试文档,如测试计划、测试方案、测试用例等。
只要是软件产品,都是测试对象。
静态测试和动态测试的划分
静态测试,不运行被测对象,而是采用其他手段和技术对被测对象进行检测的一种测试技术。例如:代码走读、文档评审、程序分析都是静态测试的范畴,常用技术有静态分析技术。
动态测试,按照预先设计的数据和步骤去运行被测对象,从而对被测对象进行检测的一种测试技术,常用技术有动态分析技术。
静态测试
静态测试这里主要了解静态分析技术。
定义:静态分析是一种不通过执行程序而分析程序执行的技术。
功能:检查软件的表示和描述是否一致,没有冲突或者没有歧义,它的目标是纠正软件系统在描述、表示和规格上的错误,因此是任何进一步测试执行的前提。
主要有三种不同的程序测试可能性:
- 规格考虑,程序是否满足编码,语法上是否具有一致性和完整性。
- 考虑文档描述是否规范、准确、是否便于查阅,例如描述是否不清楚、出现歧义等。
- 考虑程序和文档之前的一致性,例如文档要求某文件大于1M抛出错误,而程序则是大于等于1M诸如此类的问题。
关于规格考虑的可以参考下面示例。
def foo():
l = [3, 5, 8, 10]
if l[4] < 10: # l[4]超出列表的索引下标3
print("ok")
while l[3] < 12: # 死循环
print("ok")
比如上例中的foo函数,第一个if条件是错误的,包括while循环都是有问题的,这些都是我们要考虑的问题,如这个函数语法问题,缩进问题、逻辑问题、是否有恰当的注释。
静态分析技术结构
手工静态分析——同行评审
静态分析技术中一个最重要的手工技术是同行评审,根据形式正规的程度分为:
- 正规检视,指定的人员参与、相关会议、相关文档都是比较正规的。
- 技术评审。
- 走查。
同行评审的对象可以是计划、需求文档、设计图、源代码等。
如下图,在瀑布模型中,贯穿整个开发过程中的评审。
自动化静态分析
静态验证检测规格到程序实现之间的转换上的问题,验证器需要有形式化的规格和规格的形式化定义,静态验证比较程序提供的设计值和在规格文档中被预先定义的目标值。
语法分析器是一个基本的自动化静态分析工具,它把程序/文档文本分解成独立的语句,当在内部检查程序/文本的时候,语句的一致性被进行了检查。
符号执行器在符号短语中分析一个程序在给定的路径上做了什么事情,它模拟程序的执行,计算在程序不同位置上变量的值,符号执行器非常适用于数学算法的分析。
动态测试
动态测试这里主要了解动态分析技术。
定义:对软件系统运行行为进行分析,包含程序在受控的环境下使用特定的输入进行正式的运行,然后和期望的结果比较以检查系统运行时正确还是不正确。
常用的动态分析技术:
- 路径测试
- 分支测试
- 性能测试
常用动态分析工具功能
动态分析类 | 工具的功能 |
---|---|
测试覆盖率分析 | 测试对代码的检测范围 |
跟踪 | 跟踪程序执行期间的所有路径,例如所有变量的值等 |
调整 | 度量程序执行过程中使用的资源 |
模拟 | 模拟系统的一部分,例如无法获得的代码或者硬件 |
断言检查 | 测试在复杂逻辑结构中是否某个条件已被给出 |
常用黑盒动态测试工具
常用的黑盒动态测试主要测试内容包括:
- 功能测试。
- 性能测试。
- 回归测试。
在上述测试中,我们会用到:
- QARun
- Robot
- QTP
- SikTest
- LoadRunner
- SilkPerformer
上述这些工具各有特点,应用于不同的测试中,完成测试任务,比如性能测试。
人工测试、自动化测试
人工测试:测试活动(评审、测试设计、测试执行)由人来完成,狭义上是指测试执行由人工完成,这是最基本的测试形式。
自动化测试:一般指通过计算机模拟人的测试行为,替代人的测试活动,狭义上是指测试执行由计算机来完成。
适合自动化测试的活动
适合自动化的活动包括重复多次、机械是的测试,可以使用自动化来执行自动化的执行与检查校验。
自动化测试的意义
对于程序新版本运行前一版执行的测试,提高回归测试效率。
可以运行更多更频繁的测试,比如冒烟测试。
可以执行手工测试困难或者不可能做的测试,比如大量的重复操作或者集成测试。
更好的利用资源,比如测试仪器或者被测对象。
测试具有一致性和可重复性,即即自动化测试的步骤和结果是完全一致的。
测试的复用性,即自动化测试脚本可以拆分开给其他测试脚本使用。
可以更快的将软件推向市场,软件发布前进行高效的回归测试,减少软件发布的时间。
增加软件信任度,通过自动化测试提高了测试效率,可以把节约的时间拿出来做更多的测试。
自动化测试的分类
- 按照测试目的大致分为:功能自动化测试、性能自动化测试。
- 按照测试对象可划分:web自动化测试、APP方向自动化测试、接口自动化测试、单元测试等。
- 其他的包括代码测试和数据测试等。
自动化测试解决了哪些问题
- 回归测试:项目在发布新版之后,对之前的功能进行验证。
- 压力测试:统计软件服务器处理并发的能力,比如能支持多少个用户同时访问。
- 兼容性测试:不同的系统平台,或者不同的浏览器。
- 提高测试效率,保证了产品的质量。
自动化测试具有提高任何软件长期效率的特定优势。测试自动化的主要优点是:
- 长期以来,自动化测试一直被认为对大型软件组织有益。虽然,小型公司通常认为实施起来太昂贵或困难。
- 可以对自动化测试工具进行编程,以便在特定时间构建和执行测试脚本,而无需任何人为干预。例如,自动测试可以在一夜之间自动启动,测试人员可以在第二天早上分析自动化结果。
- 自动化测试工具能够播放预先录制和预定义的动作。
- 自动化测试支持频繁的回归测试,这也是自动化测试的主要任务。
- 它为开发人员提供快速反馈。
- 它提供了无限次的测试用例执行迭代。
- 它提供了有关测试用例的严格文档。
- 自动化测试生成定制的缺陷报告。
- 与手动测试相比,更不容易出错。
- 可以执行更多繁琐且枯燥的测试。
- 可以执行一些手工测试困难或者不可进行的测试。
- 更好的利用资源,在某些方面解放测试人员。
- 让具有一致性和可重复性的测试用例复用起来更加简单。
- 提高被测软件的可靠性。
适合自动化测试的场景
- 测试任务明确,不会频繁变动。
- 软件需求变更较少。
- 项目周期长,测试脚本可以复用。
自动化测试的限制
不能取代手工测试,自动化测试只能提高测试效率,不能提高测试有效性,即不可能发现更多缺陷。
手工测试比自动化测试发现的缺陷更多。
对测试设计依赖性极大,测试设计的不好会遗漏问题。
自动化测试对软件开发具有很大的依赖性,开发上出现变更可能导致前面的自动化测试完全失效。
工具本身并不具备想象力。
自动化用于功能自动化的测试工具
- 由HP提供的Quick Test Professional。
- Rational Robot,由IBM提供。
- Coded UI,由Microsoft提供。
- Selenium,开源软件。
- Auto It,开源软件。
自动化测试生命周期
Web应用程序的测试自动化
如果我们看一下目前市场情况中普遍存在的软件应用程序的类型,大多数软件应用程序都是作为基于Web的应用程序编写的,以便在互联网浏览器中运行。基于Web的应用程序的测试策略在公司和组织之间差异很大。在高度交互和响应迅速的软件过程的时代,许多组织正在使用某种形式的敏捷方法,测试自动化经常成为软件项目的要求。
为Web应用程序执行测试自动化的最有效方式是采用金字塔测试策略。此金字塔测试策略包括三个不同级别的自动化测试。单元测试代表了此测试自动化金字塔的基数和最大百分比。 接下来是服务层或API测试。最后,GUI测试位于顶部。金字塔看起来像这样:
自动化测试的误区
不现实的期望,希望自动化能取代手工测试。
缺乏测试实践经验,手工测试都做不好,或者经验积累不足,就尝试自动化,很难成功。
期望自动化测试发现大量新缺陷,自动化只能保证测试执行效率,确保已有问题不会再发生,发现新缺陷不是器目的。
安全性错觉,认为进行了自动化测试的软件就是安全的,质量有保证的。
只有手工测试做好了,明确了测试观察点,才能把自动化测试做好,所以手工测试是自动化测试的基础。
进行自动化测试考虑因素
我们从以下六个方面来考虑是否进行自动化测试:
- 进度要求:开发周期短,产品迭代快,这个时候,我们没有时间来进行自动化,因为自动化需要大量的准备时间。
- 人力要求:自动化的用例设计,执行、维护都需要大量的人力,这个时候,你是否有足够的人类来展开自动化测试。
- 版本稳定情况:如果开发不断地迭代版本,那么你就要考虑自动化的维护成本了,是否值得自动化测试。
- 版本应用情况:如果在相当长的时间内,软件后续不在更新迭代,我们没有必要进行自动化。
- 版本规模:如果用例的规模本来就很小,比如说就百十来个,那就没必要进行自动化测试。
- 自动化率:加入测试用例是1000个,而其中只有十几个或几十个用例可以进行自动化测试,那么我们不考虑自动化,只有当可以自动化的用例占比超过20%的时候,我们才考虑进行自动化测试。
编写用例的几种方法
在编写测试用例的时候,我们可以有以下几种形式来完成:
- 等价类划分法(5星)
- 边界值法(5星)
- 场景法(5星)
- 因果图法
- 判定表法
- 正交(排列)法
- 测试大纲法
我们至少要了解每种方法的使用场景(在哪用?)和使用步骤(怎么用?)。
除此之外,我们编写测试用例,都有哪些可以参考的呢?
- 需求文档
- 被测系统(已经开发出来的被测系统),一边对照程序,一边编写用例,很多企业都采用这种方式,如果只对照需求文档可能仅能完成测试的30~40%。
- 开发(设计)文档,当然,有可能也拿不到,比如说开发和测试分属不同的公司,人家开发就不一定提供文档。
- 积极与开发、产品、客户进行沟通
接下来,我们来了解各各方法都是怎么玩的。
等价类划分法
现在,进入讨论时间,我们要对计算器进行测试的话,到底要输入多少组测试数据才算测试完毕?
这个答案很难回答啊,一个一个测试的话, 那能测到天荒地老,媳妇怀孕......
所以,我们要采用分类测试:
- 整数,比如在范围(-100~100)内取最大、最小、中间值
- 小数,比如在范围(-100~100)内取最大、最小、中间值
- 符号,各种符号(!@#、、)
- 汉字或其他语言、字母
- 空格
- 空值,也就是什么都不输入
通过上面的分类,我们发现用户所有可能输入的数据,划分为了若干份(或称为不同的子集),然后从每个子集中选取少数具有代表性的数据作为测试用例,这种测试用例我们称为等价类(类别)划分法。
等价类划分法是一种重要的、常用的黑盒测试方法,无需考虑程序的内部结构,只需要考虑程序的输入规格即可,它将不能穷举的测试过程进行合理的分类,从而保证设计出来的测试用例具有完整性和代表性。
在有限的测试资源的情况下,用少量有代表性的数据得到比较好的测试效果。
等价类划分分为(基本概念):
- 有效等价类,指符合《需求规格说明书》,输入合理的数据集合。
- 无效等价类,指不符合《需求规格说明书》,输入不合理的数据集合。
等价类思考步骤:
- 首先确定有效等价类和无效等价类
- 有效等价类就是一目了然的题目条件(比如在0~20之间测试),要考虑到两端的极值(边界值)和中间值。
- 无效等价类先划分与条件相反的情况(比如不在0~20范围内),再去找特殊情况,如中英文,符号、空格、空等。
示例1:计算整数
计算1 ~ 20的整数之和(包括1和20)。
新建一个Excel表格,在Excel表格中建立等价类的划分:
用例编号 | 所属等价类 | 输入值1 | 输入值2 | 预期结果 | 是否提bug |
---|---|---|---|---|---|
1 | 有效 | 1~20整数 | 8 | 正确 | |
2 | 有效 | 8 | 1~20整数 | 正确 | |
3 | 无效 | 小于1 | 8 | 错误 | |
4 | 无效 | 8 | 小于1 | 错误 | |
5 | 无效 | 大于20 | 8 | 错误 | |
6 | 无效 | 8 | 大于20 | 错误 | |
7 | 无效 | 中文 | 8 | 错误 | |
8 | 无效 | 8 | 中文 | 错误 | |
9 | 无效 | 英文 | 8 | 错误 | |
10 | 无效 | 8 | 英文 | 错误 | |
11 | 无效 | 特殊符号 | 8 | 错误 | |
12 | 无效 | 8 | 特殊符号 | 错误 | |
13 | 无效 | 空格 | 8 | 错误 | |
14 | 无效 | 8 | 空格 | 错误 | |
15 | 无效 | 空 | 8 | 错误 | |
16 | 无效 | 8 | 空 | 错误 | |
17 | 无效 | 小数 | 8 | 错误 | |
18 | 无效 | 8 | 小数 | 错误 |
注意:一般的,我们在输入测试时,一个值是正确的,另一个值是错误的,而不是两个值都是错误的,因为这样更容易确定到底哪个值是错误的。如果不符合预期,那么就要提交bug了。另外,一定要根据需求来判断结果到底是错误的还是正确的。
我们也可以通过Python代码来实现一个最简单的计算器:
import os
print('计算1~20内的两数之和,包含1和20')
def add(x, y):
return int(x) + int(y)
while True:
try:
num1 = input('请输入一个值或输入 q 退出: ').strip()
if num1.upper() == 'Q':
break
num2 = input('再次输入一个值: ').strip()
os.system('cls')
print('{} + {} = {}'.format(num1, num2, add(num1, num2)))
except Exception as e:
print(e)
也可以使用pyinstaller
将Python文件转成可执行文件:
# 首先要先下载pyinstaller
pip install installer
# 将指定文件转换为可执行文件
pyinstaller -F t1.py
示例2:测试QQ账号
要求是账号必须是6~10位数的正整数。
所以,我们分析来分析有效等价类和无效等价类:
- 有效等价类:长度在6~10位之间的正整数
- 无效等价类:
- 长度小于6
- 长度大于10
- 负数
- 小数
- 中文
- 英文字母
- 空格
- 特殊字符
按照老套路来,我们在Excel中进行等价类的划分。
用例编号 | 等价类划分 | 账号框 | 预期结果 | 是否提bug |
---|---|---|---|---|
1 | 有效 | 6~10位正整数 | 正确 | |
2 | 无效 | 小于6位 | 错误 | |
3 | 无效 | 大于10位 | 错误 | |
4 | 无效 | 负数 | 错误 | |
5 | 无效 | 小数 | 错误 | |
6 | 无效 | 中文 | 错误 | |
7 | 无效 | 英文 | 错误 | |
8 | 无效 | 空格 | 错误 | |
9 | 无效 | 特殊字符 | 错误 | |
10 | 无效 | 空 | 错误 |
上例是以qq账号为例,并没有提密码的事情,所以,我们仅关注输入的值是否符合题意要求,与预期不符则提交bug。
用Python代码实现如下:
import os
print('QQ账号测试,要求是必须是6~10位正整数')
while True:
try:
num1 = input('请输入一个值或输入 q 退出: ').strip()
if num1.upper() == 'Q':
break
if num1.isdigit():
if 6 <= len(num1) <= 10:
print('输入 {} 正确,长度为 {}'.format(num1, len(num1)))
else:
print('输入的 {} 长度为 {} 位,不符合题意要求'.format(num1, len(num1)))
else:
print('输入的 {} 不符合题意要求'.format(num1))
os.system('cls')
except Exception as e:
print(e)
示例3:测试电话号码
某电话号码由3部分组成,分别是:
- 地区码:空白或者3位数字
- 前缀:非
0
且非1
开头的三位数 - 后缀:4位数字
用例编号 | 等价类划分 | 电话组成 | 输入内容 | 预期结果 | 是否提交bug |
---|---|---|---|---|---|
1 | 有效 | 地区码 | 空白或3位数字 | 正确 | |
2 | 无效 | 地区码 | 大于3位 | 错误 | |
3 | 无效 | 地区码 | 小于3位 | 错误 | |
4 | 无效 | 地区码 | 中文 | 错误 | |
5 | 无效 | 地区码 | 英文 | 错误 | |
6 | 无效 | 地区码 | 空格 | 错误 | |
7 | 无效 | 地区码 | 特殊字符 | 错误 | |
8 | 无效 | 地区码 | 小数 | 错误 | |
9 | 有效 | 前缀 | 非0 且非1 开头的三位数 |
正确 | |
10 | 无效 | 前缀 | 0开头 | 错误 | |
11 | 无效 | 前缀 | 1开头 | 错误 | |
12 | 无效 | 前缀 | 大于3位 | 错误 | |
13 | 无效 | 前缀 | 小于3位 | 错误 | |
14 | 无效 | 前缀 | 中文 | 错误 | |
15 | 无效 | 前缀 | 英文 | 错误 | |
16 | 无效 | 前缀 | 空格 | 错误 | |
17 | 无效 | 前缀 | 特殊字符 | 错误 | |
18 | 无效 | 前缀 | 小数 | 错误 | |
19 | 有效 | 后缀 | 4位数字 | 正确 | |
20 | 无效 | 后缀 | 大于4位 | 错误 | |
21 | 无效 | 后缀 | 小与4位 | 错误 | |
22 | 无效 | 后缀 | 中文 | 错误 | |
23 | 无效 | 后缀 | 英文 | 错误 | |
24 | 无效 | 后缀 | 空格 | 错误 | |
25 | 无效 | 后缀 | 特殊字符 | 错误 | |
26 | 无效 | 后缀 | 小数 | 错误 |
示例4:用户登录
要求:
- 用户名(昵称)长度为3~19,以字母开头
- 登录名称:非空
- 密码:非空
- 确认密码:值和密码相同
接着打开Excel表格,来罗列测试用例:
用例编号 | 等价类划分 | 用户输入文本框 | 输入内容 | 预期结果 | 是否提bug |
---|---|---|---|---|---|
1 | 有效 | 用户名、昵称 | 以字母开头,长度3~19位 | 正确 | |
2 | 无效 | 用户名、昵称 | 小于3位 | 错误 | |
3 | 无效 | 用户名、昵称 | 大于19位 | 错误 | |
4 | 无效 | 用户名、昵称 | 数字 | 错误 | |
5 | 无效 | 用户名、昵称 | 小数 | 错误 | |
6 | 无效 | 用户名、昵称 | 中文、特殊符号 | 错误 | |
7 | 无效 | 用户名、昵称 | 空格 | 错误 | |
8 | 无效 | 用户名、昵称 | 空 | 错误 | |
9 | 无效 | 用户名、昵称 | 被和谐掉的词 | 错误 | |
10 | 有效 | 登录名称 | 非空 | 正确 | |
11 | 无效 | 登录名称 | 空 | 错误 | |
12 | 有效 | 密码 | 非空 | 正确 | |
13 | 无效 | 密码 | 空 | 错误 | |
14 | 有效 | 确认密码 | 与密码相同 | 正确 | |
15 | 无效 | 确认密码 | 与密码不一致 | 错误 |
小结,在等价类划分中,我们可以从以下几个角度考虑:
- 文本框要求输入的长度
- 输入的类型
- 组成规则
- 是否为空
- 是否重复
- 区分大小写
- 是否去空格
等价类划分法的应用场景
- 有数据输入的地方
- 从大量的数据中挑选少量有代表性的数据进行测试
等价类划分发的测试思想
- 穷举测试:把所有可能的数据全部测试一遍称为穷举测试,虽然穷举测试是最全面的测试,但是很明显不现实,因为测试效率太低了,数据量巨大,根本测不过来(思考前面计算器的例子)。但又因为没有做过穷举测试,所以会有遗漏缺陷的风险,如果时间允许,尽可能的做补充测试(觉得有风险有问题的做补充测试)。
- 理想的测试思想,使用最少的测试数据,达到最好的测试质量,毕竟性价比还是要追求的嘛。
- 而等价类划分法则是从大量的数据中,划分范围(或分类),每个范围内的数据测试效果是等价的,所以每个范围是一个等价类,然后从每个范围内挑选出具有代表性的数据,这些代表数据能反映这个范围内的测试结果。
- 等价类划分法的基本思想是:
- 有效等价类,对于程序来说,是有意义的,合理的输入数据集合,然后测试功能是否符合预期。
- 无效等价类,对于程序来说,是无意义的,不合理的输入数据集,用来测试程序是否具有强大的异常处理能力,也就是测试程序的健壮性。
边界值
什么是边界值?
边界是指对于输入等价类和输出等价类而言,稍高于边界值和稍低于边界值的一些特定情况,边界值分析法常应用于黑盒测试中。边界值也可以称为极值。
根据以往的经验来看:大量的错误是发生在输入或者输出范围的边界上,而不是再输入范围的内部。所以,为了保证测试质量,我们需要重点关注测试边界。
让我们通过示例来加深理解。
示例:输入的值必须在大于0且小于100的整数
我们通过一个简单示例来观察:
res = input('输入0~100内的整数: ').strip()
if res.isdigit():
res = int(res)
if 0 <= res <= 100: # 程序员可能会因为疏忽将大于写成大于等于
print('输入的值必须大于0且小于100,你输入的是 {}'.format(res))
else:
print('输入错误')
else:
print('非法输入')
上例中,程序员把边界值条件设置错了,把>
写成了>=
,把<
写成了<=
。
注意:有效数据和无效数据的分界点,往往作为程序员编写程序的判断点,所以,这也是程序员最容易犯错的地方(他很有可能听着歌,脑子里想着是大于小于,结果手比脑子动的快,写成小于等于等等情况),所以,边界值这里是我们测试人员重点测试的地方。
那么如何解决这类问题?
- 找到测试数据的边界点,也就是有效等价类和无效等价类的边界点,对于边界点数据专门进行测试。
- 一般的,测试人员需要对边界值及边界值两边的数分别进行测试。
示例:完善用户登录
让我们来完善之前等价类划分发中的用户登录示例。仅拿出一个要求进行分析。用户名、昵称这里要求是3~19位。
用例编号 | 等价类划分 | 用户输入文本框 | 输入内容 | 预期结果 | 是否提bug |
---|---|---|---|---|---|
1 | 有效 | 用户名、昵称 | 以字母开头,长度3~19位 | 正确 | |
2 | 无效 | 用户名、昵称 | 小于3位 | 错误 | |
3 | 无效 | 用户名、昵称 | 大于19位 | 错误 |
通过上表可以看到,我们之前仅判断了边界值,但是不够精细,我们来完善一下。就是对边界值及边界值两边的数据进行测试。那么边界值3,就要测试2, 3, 4;而边界值19,就要测试18,19,20。
用例编号 | 等价类划分 | 用户输入文本框 | 输入内容 | 预期结果 | 是否提bug |
---|---|---|---|---|---|
1 | 有效 | 用户名、昵称 | 以字母开头,长度3~19位 | 正确 | |
2 | 无效 | 用户名、昵称 | 等于2 | 错误 | |
3 | 有效 | 用户名、昵称 | 等于3 | 正确 | |
4 | 有效 | 用户名、昵称 | 等于4 | 正确 | |
5 | 有效 | 用户名、昵称 | 等于18 | 正确 | |
6 | 有效 | 用户名、昵称 | 等于19 | 正确 | |
7 | 无效 | 用户名、昵称 | 等于20 | 错误 |
通过对边界值及边界值两边的数据都进行测试,提高测试质量。
确定边界值的一般思路
- 确定边界情况,也就是确定输入或者输出等价类的边界
- 选取正好等于、刚刚大于、刚刚小于边界值作为测试数据
- 边界值的取值依据输入范围区间不同而有所不同,但是都需要把上点值、离点值、和内点值取到。如下表所示:
区间 | 上点 | 内点 | 离点 |
---|---|---|---|
闭区间,如[1, 10] | 1,10 | 5 | 0,11 |
开区间,如(1, 10) | 1,10 | 5 | 2,9 |
半开半闭区间,如(1, 10] | 1,10 | 5 | 2,11 |
示例1:标题
使用边界值的方法设计添加标题的测试用例,要求是:标题长度大于0,标题长度小于等于30
用例编号 | 输入值 | 预期输入 | 是否提交bug | 备注 |
---|---|---|---|---|
1 | 空白 | 错误 | 0字节 | |
2 | 等于30 | 正确 | 30字节 | |
3 | 大于30 | 错误 | 大于30字节 | |
4 | 小于30 | 正确 | 1~29字节 | |
5 | 小于等于0 | 错误 | 0字节 |
示例2:成绩测试
输入一个学生的成绩,判断是否及格(0~100间的整数):
- 确定有效区域和无效区域。
- 临界点:0、60、100。
- 取值:-1、0、1、59、60、61、99、100、101。
来搞测试用例:
用例编号 | 等价类划分 | 成绩 | 预期结果 | 是否提交bug |
---|---|---|---|---|
1 | 有效 | 0 | 不及格 | |
2 | 有效 | 1 | 不及格 | |
3 | 有效 | 59 | 不及格 | |
4 | 有效 | 60 | 及格 | |
5 | 有效 | 61 | 及格 | |
6 | 有效 | 99 | 及格 | |
7 | 有效 | 100 | 及格 | |
8 | 无效 | 101 | 错误 | |
9 | 无效 | -1 | 错误 | |
10 | 无效 | 小于0 | 错误 | |
11 | 无效 | 大于100 | 错误 | |
12 | 无效 | 空 | 错误 | |
13 | 无效 | 中、英文 | 错误 | |
14 | 无效 | 特殊符号、小数 | 错误 |
有了上表,我们能一目了然的观察出有效无效等价类,并在其中应用了边界值。
示例3:密码
修改手机某软件登录密码框,要求:
- 密码必须由字母数字组成。
- 密码长度在
8~24
之间(包含8和24)。
用例编号 | 等价类划分 | 输入框 | 预期结果 | 是否提交bug |
---|---|---|---|---|
1 | 有效 | 8位数字和字母组合 | 正确 | |
2 | 有效 | 9位数字和字母组合 | 正确 | |
3 | 有效 | 23位数字和字母组合 | 正确 | |
4 | 有效 | 24位数字和字母组合 | 正确 | |
5 | 无效 | 7位数字和字母组合 | 错误 | |
6 | 无效 | 25位数字和字母组合 | 错误 | |
7 | 无效 | 小于8位数字和字母组合 | 错误 | |
8 | 无效 | 大于24位数字和字母组合 | 错误 | |
9 | 无效 | 中文 | 错误 | |
10 | 无效 | 特殊符号 | 错误 | |
11 | 无效 | 空格 | 错误 | |
12 | 无效 | 空 | 错误 | |
13 | 无效 | 8位数字 | 错误 | |
14 | 无效 | 9位数字 | 错误 | |
15 | 无效 | 23位数字 | 错误 | |
16 | 无效 | 24位数字 | 错误 | |
17 | 无效 | 7位数字 | 错误 | |
18 | 无效 | 25位数字 | 错误 | |
19 | 无效 | 8位字母 | 错误 | |
20 | 无效 | 9位字母 | 错误 | |
21 | 无效 | 23位字母 | 错误 | |
22 | 无效 | 24位字母 | 错误 | |
23 | 无效 | 7位字母 | 错误 | |
24 | 无效 | 25位字母 | 错误 |
边界值的方法思考:
- 如果输入条件规定了范围,则应该取这个范围的边界值,比如
1~100
,边界值应该取0 1 100 101
。 - 如果输入条件规定了输入值的个数。比如密码长度为
8~24
,边界值应该取7 8 9 23 24 25
位字符来判断。 - 边界值和等价类的区别,边界值分析不是从等价类中随便找一个作为代表,而是整个等价类的每个边界都要作为测试条件。
- 边界值的思想是在结合实际环境,应该选出到边界和刚超过的值作为测试依据。边界值和等价类是相辅相成的,共同使测试用例更加完善。
常见的边界值:
- 循环中的第1、2次和倒数第1、2次。
- 数值元素的第一个和最后一个值。
- 报表的第一行和最后一行。
- 文本框接收字符个数,用户名长度啊,密码长度等。
在这些长度、个数什么的,要多考虑边界值。
see also :测试用例--等价类划分、边界值法
因果图
因果图(Cause-Effect Graph)法是一种利用图解法分析输入的各种组合情况,从而设计测试用例的方法,它适用于检查程序输入条件的各种组合情况。
因果图法的特点
- 考虑输入条件的相互制约及组合关系
- 考虑输出条件对输入条件的依赖关系
因果图法产生的背景
- 等价类划分法和边界值分析方法都是着重的考虑输入条件,但是极少的考虑输入条件的各种组合、输入条件之间的相互制约关系,这样虽然各种输入条件可能出错的情况已经测试到了,但是多个输入条件组合起来可能出错的情况却很难发现。
- 如果在测试的时候,必须考虑输入条件的组合情况,那么可能的组合情况将非常的多,导致测试任务繁重。因此,我们必须考虑一种适合于描述多种条件的组合,相应产生多个动作的形式来进行测试用例的设计,这就用到了因果图,也就是设计逻辑模型。
因果图的核心
- 因果图法适用于输入条件较多的情况,测试所有输入条件的排列组合。因果图所谓的因就是输入,而果就是输出。
- 因果图之
因
,及输入条件。 - 因果图之
果
,即输出结果。
- 因果图之
因果图法要注意考虑的要点
- 所有输入/输出条件的相互制约关系及组合关系。
- 输出结果对输入条件的依赖关系,也就是什么样的输入组合会产生怎样的输出结果,即
因果关系
。
因果图中的基本符号
通常在因果图中,用Ci表示原因,用Ei表示结果,各节点表示状态,可取值0
或1
,0
表示某状态不出现,1
表示某状态出现。
-
恒等,若原因出现,则结果出现,若原因不出现,结果也不出现。
- 若
c1 = 1
,则e1 = 1
。 - 若
c1 = 0
,则e1 = 0
。
例如ATM机取钱,打印凭条。
- 若
-
非(~),若原因出现,则结果不出现,若原因不出现,则结果出现。
- 若
c1 = 1
,则e1 = 0
。 - 若
c1 = 0
,则e1 = 1
。
搜索QQ好友,如果有就不提示错误,如果没有就提示错误。
- 若
-
或(∨),若几个原因中有一个出现,则结果出现,若几个原因都不出现,则结果不出现。
- 若
c1 = 1 or c2 = 1 or c3 = 1
,则e1 = 1
。 - 若
c1=c2=c3=0
,则e1 = 0
。
暖宝宝
+热心
+细心
▶滴,好人卡!
- 若
-
与(∧),若几个原因都出现,则结果才出现,若其中一个原因不出现,则结果不出现。
- 若
c1 = 1 and c2 = 1
,则e1 = 1
。 - 若
c1 = 0 or c2 = 0
,则e1 = 0
。
暖男
+热心
+细心
▶滴,烂好人!
- 若
小结:
- 恒等,有因有果,无因无果。
- 与(且),条件都为真,结果才为真,如果其中一个条件为假,则结果为假。
- 或,有一个条件为真,则结果为真,条件都为假,结果才为假。
- 非,取反的意思,有因无果,无因有果。
因果图中的约束条件(了解)
因果图法基本步骤
利用因果图到处测试用例需要经过一下几个步骤:
- 找出所有的原因,原因即是输入条件或输入条件的等价类。
- 找出所有的结果,结果即输出条件。
- 明确所有输入条件之间的制约关系及组合关系。比如,哪些条件可以组合到一起,哪些条件不能组合到一起。
- 明确所有输出条件之间的制约关系以及组合关系。比如,哪些输出结果可以同时输出,哪些输出结果不能同时输出。
- 找出什么样的输入条件组合会产生哪种输出结果。
- 把因果图转换成判定表/决策表。
- 为判定表/决策表中的每一列表示的情况设计测试用例。
示例:一卡通自动充值系统
要求:
- 系统只接收50或100元纸币,一次只能使用一张纸币,一次充值金额只能为50元或者100元。
- 若输入50元纸币,并选择充值50元,完成充值后退卡,提示充值成功。
- 若输入50元纸币,并选择充值100,提示输入金额不足,并退出50元。
- 若输入100元纸币,并选择充值100元,完成充值侯退卡,提示充值成功。
- 若输入纸币后在规定的时间内不选择充值按钮,退出输入的纸币,并提示错误。
- 若选择充值按钮后不输入纸币,提示错误。
根据需求,分析
- 找出所有输入条件编号
- 找出所有输出条件编号
- 找出所有输入、输出的制约关系
先来看输入的因果关系图:
- ① 输入50元。
- ② 输入100元。
- ③ 选择充值50元。
- ④ 选择充值100元。
输出关系因果图:
- a. 完成充值、退卡。
- b. 提示充值成功。
- c. 找零。
- d. 提示错误。
由图可以看到,1
和2
之间的关系是互斥的,3
和4
也是互斥的。
再来看它们组成的因果图:
输入结论:
- 条件1和条件2不能组合。
- 条件3和条件4不能组合。
- 条件1和条件3可以组合。可以得出输出a和b组合。
- 条件1和条件4可以组合。
- 条件2和条件3可以组合。
- 条件2和条件4可以组合。
- 各条件可以单独出现。
输出结论:
- 输出b和d不能组合。
- 输出a和b必须组合。
- 输出a、b、c可以组合。
- 输出d可以单独存在。
由分析得出,哪些条件可以组合在一起,哪些条件不能组合在一起。
根据上面的输入输出,我们来实现各用例:
- 条件1和条件3可以组合,得出输出a和b组合。
- 条件1和条件4可以组合,得出输出c和d组合。
- 条件2和条件3可以组合,得出a、b、c组合。
- 条件2和条件4可以组合,得出输出a和b组合。
- 条件1单独出现,得出c和d组合。
- 条件2单独出现,得出c和d组合。
- 条件3单独出现,得出d组合。
- 条件4单独出现,得出d组合。
上述各因果图汇总如下:
看着是不是疯了?所以,这种因果图只是辅助我们理解,不是必须要画出来的。当我们熟悉了之后,这个图就出现在我们心里了,所谓的手中无图在心中(妈的,我连我自己都骗!)。
上述各用例用我们熟悉的表怎么表示呢?
判定表
因果图只是一种辅助工具,我们通过因果图分析出一个表,这个表就是判定表,然后通过判定表编写测试用例。但是有的时候,画因果图非常麻烦,影响测试效率,所以,我们很多时候都是直接写判定表,进而编写测试用例。
判定表的组成
- 条件桩:问题的所有条件,即所有的条件组合。
- 动作桩:问题的所有输出,即所有的输出组合。
- 条件项:针对条件桩的取值。
- 动作项:条件项的各种取值情况下的输出结果。
判定表制作步骤
- 列出所有的条件桩和动作桩。
- 填入条件项与动作项,得到初始判定表。
- 简化判定表(合并相似规则(相同动作))。
示例:好学生判定
在遵纪守法的前提下:
- 学习好是好学生。
- 品德好是好学生。
- 只要违法乱纪就是绝对不是好学生;成绩和品德只有要有一项,再加上遵纪守法也是好学生。
我们根据条件列出判定表:
当然,还可以合并一些条件,比如说,只要遵纪守法再加学习和成绩二选一都算是好学生;另外,只要不遵纪守法,学习再好,品德再高也不算好学生。所以,我们可以合并整理一下:
注意:合并使用-
,表示无关条件,选什么都不影响结果。虽然在一定程度上,减少了表格列举数量,但是-
带来了条件模糊的情况(比如用例5、6、7、8中,在编写用例的时候,还是要查询-
代表的条件),所以,尽量还是按照原来的表格一一列举,这有助于用例的编写。
场景法
场景法就是模拟用户操作软件时的场景,主要用于测试系统的业务流程。
- 当接到一个测试任务时,我们并不关注某个控制的边界值,等价类是否满足要求。而是要关注它的主要功能和业务流程是否正确实现,这就需要使用场景法来完成测试。
- 当业务流程没问题时,即软件的主要功能没有问题时,我们再重新从边界值、等价类方面对软件进行测试。
在冒烟测试时也主要采用场景法进行测试。
用例场景定义
在场景法中有两个重要的概念:
- 基本流:按照正确的业务流程来实现一条操作路径,即模拟正确的操作流程。
- 备选流:导致程序出现错误的操作流程,即模拟错误的操作流程。
用例场景使用来描述流经用例路径的过程,这个过程从开始到结束遍历用例中所有的基本流和备选流。
用例场景产生的背景
现在的软件几乎都是由事件触发来控制流程的,事件触发时的情景便形成了场景,而同一事件因不同的触发顺序和处理结果形成事件流。
将这种在软件设计方面的思想引入到软件测试中,生动的描绘出时间触发时的情景,有利于测试设计者测试用例,同时测试用例也更容易得到理解和执行。
- 在使用场景法设计测试用例时,需要覆盖系统用例中的主成功场景和扩展场景。并且需要适当补充各种正反面的测试用例和考虑出异常场景的情形。
- 当使用场景测试软件没有问题时,可以再使用边界值、等价类划分法等测试方法对软件进行更加细致、完整的测试。
案例:测试QQ登录功能
QQ登录有以下情景:
- 账号、密码无误,点击登录,程序能正常登录。
- 账号正确、密码错误,点击登录,程序给出错误提示。
- 账号正确、不输入密码,点击登录,程序给出错误提示。
- 不输入账号和密码,点击登录,程序给出错误提示:“请您输入账号后登陆”。
- 不输入账号,输入正确的密码,点击登录,程序给出错误提示。
- 输入错误的账号,正确的密码,点击登录,程序给出错误提示。
其实,场景法很简单,我们只需要将每一个业务需求,当成测试用例就可以了。
我们来实现相应的用例:
用例编号 | 场景(条件) | 账号 | 密码 | 预期结果 | 是否提bug |
---|---|---|---|---|---|
1 | 账号、密码无误 | Y | Y | 程序正常登录 | |
2 | 账号正确、密码错误 | Y | N | 程序给出错误提示 | |
3 | 账号正确、不输入密码 | Y | 空 | 程序给出错误提示 | |
4 | 不输入账号和密码,点击登录 | 空 | 空 | 请您输入账号后登陆 | |
5 | 不输入账号,输入正确的密码 | 空 | Y | 程序给出错误提示 | |
6 | 输入错误的账号,正确的密码 | N | Y | 程序给出错误提示 |
总结:只要把需求一条一条的列出来,当成测试用例。再增加写注意事项,当然,一般产品经理也会提供这些注意事项。
流程分析法
流程分析法主要是针对测试场景类型,属于流程测试场景的测试项下的一个测试子项进行设计。是从白盒测试设计方法中的路径覆盖分析法借鉴过来的一种方法。
- 在白盒测试中,路径就是指函数代码的某个分支组合,路径覆盖法需要构造足够的用例,以覆盖函数的所有代码路径。
- 在黑盒测试中,若将软件系统的某个流程看成路径的话,则可以针对该路径使用路径分析法设计测试用例。
优点
- 降低了测试用例的设计难度,只要搞清楚各种流程,就可以设计出高质量的测试用例来,而不需要太多测试方面的经验。
- 在测试时间较为紧迫的情况下,可以有的放矢的选择测试用例,而不用完全根据经验来取舍。
流程分析法的实施步骤
- 详细了解需求。
- 根据需求说明或界面原型,找出业务流程的各个页面以及各个页面之间的流转关系。
- 画出业务流程,由产品经理使用Axure软件制作。
- 写用例,覆盖所有的路径分支。
示例:ATM机取款
我们按照刚才的实施步骤来:
- 详细了解需求。
- 找出业务流程的各个页面以及各个页面之间的流转关系。
- 用户向ATM机插入银行卡。
- 用户输入银行卡密码。
- 用户输入取款金额。
- 银行服务器响应ATM机......点钞......扣除用户的余额.....出钞.....
- 用户取款,退卡
- 画出业务流程:
- 用例设计,写用例,覆盖所有的路径分支。
- 需求描述及流程图中,ATM取款机的提示信息对应于测试用例中的预期输出部分,用户的操作对应测试用例中的测试步骤部分。原则是一条有效路径使用一个测试用例覆盖。
- 依据业务流程图确定测试路径,即需要测试的业务流程。其主要包含三个方面:
- 正常流程,取款成功(基本流程):对应一次性取款成功。
- 异常流程,取款失败(分支流程):对应取款失败,包括退卡、吞卡。
- 异常流程,取款成功(循环流程):对应取款中间出现意外,比如密码输入错误,但是最终成功取钱的情况。
流程分析法总结
- 流程分析法适用于有先后顺序的测试。常用于业务流程测试、安装流程测试等。
- 流程分析法重点在于测试流程。因此,一般每个流程用一个测试用例验证。
- 流程测试没有问题并不能说明系统功能没有问题,还需要针对每步功能进行测试。对于包含复杂流程的系统,只有功能点和处理流程都进行测试覆盖,才算是比较充分的测试。
错误推测法(经验法)
错误推测法是指利用直觉和经验猜测出出错的可能类型,有针对性的列举出程序中所有可能的错误和容易发生错误的地方。它是骨灰级测试大佬喜欢使用的一种测试用例设计方法。
基本思想
基本思想是列举出可能犯的错误或错误易发生的清单,然后根据清单编写测试用例;这种方法很大程度上是凭经验进行的,即凭人们对过去所作测试结果的分析,对所揭示缺陷的规律性作直觉的推测来发现缺陷。
采用错误推测法,最重要的是要思考和分析测试对象的各个方面,多参考以前发现的Bug的相关数据、总结的经验,个人多考虑异常的情况、反面的情况、特殊的输入,以一个攻击者的态度对待程序,才能够设计出比较完善的测试用例。
正交测试法
现在讲述一个真实的故事:
1992 年AT&T
发表了一篇讲述在测试过程中使用正交表一个案例研究。它描述了对PC(IBM格式)和StarMail(基于局域网的电子邮件软件)做回归测试:
- 最初制定的测试计划是用18周的的时间执行1500个测试用例。但是,开发推迟了,测试时间被压缩到仅仅8周时间。
- 测试负责人采取另外一个测试方案和计划,即2个人8周的时间测试1000个测试用例,但是他不敢保证测试的质量,对这些用例检测缺陷的能力不放心。
- 为了减轻这种不确定性的问题,他用正交表法重新设计了测试用例,此时测试用例只有422个。用这422个测试用例去测试发现了41个缺陷,开发人员修复缺陷,然后软件就发布了。
- 在使用的两年时间内,凡被测试到的领域都没有再发现缺陷,因此在发现缺陷这方面,此测试计划是100%有效。
- 据测试负责人估计,如果
AT&T
采用1000个测试用例的测试计划,可能仅仅只发现这些缺陷中的32个。
与最初的计划相比,用正交表设计测试用例执行工作量不到50%,但却多发现28%的缺陷,而且测试人员个人的效率也增加了。
先来看需求。
例如,我们测试字体属性设置程序。
上图所示,在字体设置的窗口中,由若干个控件(字体、字形、字体颜色、字号),每个控件中有多个取值。比如:
- 字体:仿宋、黑体、楷体。
- 字形:常规、加粗、倾斜。
- 字号:12、14、16。
- 字体颜色:红色、绿色、蓝色。
在测试时,要考虑这些控件的组合情况,它们会有3的4次方种(81)组合。
由于组合量太大,不可能为每一种组合都创建测试用例。如何采用最少的测试用例集合获得最大的测试覆盖率——采用正交排列法。
什么是正交表?
在正式介绍正交测试法,我们先来了解两个概念:
- 什么是因素(Factor):在一项实验中,凡欲考察的变量称为因素(变量)。
- 什么是水平(位级,Level):在实验范围内,因素被考察的值称为水平(变量的取值)。
正交表是一个二维表格,它的构成如下:
-
行数(Runs):正交表中行的个数,即实验的次数(用例)。
-
因素数(Factors):正交表中列的个数。
-
水平数(Levels):任何单个因素能够取得的值的最大个数。正交表中包含的值为从0到水平数减一或从1到水平数。
-
正交表的的表示形式:
Ln(mk)Ln(mk)-
n是表的行数,也就是需要测试组合的次数。
-
k是表的列数,表示控件的个数(因素数或因子数)。
-
m是每个控件包含的取值个数(各因素的水平数,即各因素的状态数)。
-
例如我们之前的字体属性程序的需求中,可以这么列:
-
-
有4个控件。
-
每个控件有3个取值。
-
9为需要测试的组合个数。
-
也称为4因素3水平。
什么是正交表测试法?
正交测试源于正交实验设计方法。
正交试验设计方法是一种研究多因素多水平的实验设计方法,它根据正交性从全面实验中挑选出部分有代表性的点进行试验,这些有代表性的点具备了均匀分散,齐整可比的特点。
正交试验设计方法一般使用已经造好了的正交表格来安排实验并进行数据分析。
正交测试法与正交实验设计方法类似,也使用了已经造好的正交表格来生成测试用例。它简单易行,应用性较好。
正交表测试法的适用范围
正交表测试法适用于输入条件相互独立,并且需要对输入的各种组合进行测试的场合。
正交表的正交性
- 整齐可比性:在同一张正交表中,每个因素的每个水平出现的次数是完全相同的。由于在实验中每个因素的每个水平与其它因素的每个水平参与实验的几率是完全相同的,这就保证了在各水平中最大程度的排除了其他因素水平的干扰。因而能有效的进行比较和作出展望。
- 均衡分散性:在同一张正交表中,任意两列(两个因素)的水平搭配(横向形成的数字对)是完全相同的。这就保证了实验条件均衡的分散在因素水平的完全组合中,因而具有很强的代表性。
查询正交表
当然,我们无需自己去设计正交表,可以使用人家罗列好的正交表,我们只需根据被测程序选择相应的正交表。
地址1:https://www.cnblogs.com/sundawei7/p/11947499.html
地址2:https://www.york.ac.uk/depts/maths/tables/orthogonal.htm
地址3:http://support.sas.com/techsup/technote/ts723_Designs.txt
ps:正交表是经过严格的数学推理得来的!
正交测试用例设计步骤
- 根据所测程序中控件的个数(因素)以及每个控件的取值个数(水平),选取一个合适的正交排列表。
- 将控件及其取值列举出来,并对其进行编号。
- 将控件及其取值映射到正交排列表中。
- 把正交排列表中的ABCD(因子)分别替换成4个控件。
- 把每列中的1,2,3(状态)分别换成这个控件的3个取值(水平),排列顺序要按照表中给出的顺序。
- 根据映射好的正交排列表编写测试用例。
示例1:字体属性设置程序
现在,让我们使用正交表完成刚才的需求:
-
步骤1,根据被测程序中的控件个数以及每个控件的取值个数,选取一个合适的正交表。
-
由刚才的需求我们分析出:
- 有4个控件(因素):字体、字形、字体颜色、字号。
- 每个控件有3个取值(水平)。
- 所以我们选择
L9(34)L9(34)
-
我们自己整理的控件表:
编号 | 字体 | 字形 | 字体颜色 | 字号 |
---|---|---|---|---|
1 | 仿宋 | 常规 | 红色 | 12 |
2 | 黑体 | 加粗 | 绿色 | 14 |
3 | 楷体 | 倾斜 | 蓝色 | 16 |
- 步骤2,把控件及其取值列举出来,并对取值进行编号。也就将我们手动整理的控件表与正交表建立映射:
列号 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
试验号 | ||||
1 | 1 | 1 | 1 | 1 |
2 | 1 | 2 | 2 | 2 |
3 | 1 | 3 | 3 | 3 |
4 | 2 | 1 | 2 | 3 |
5 | 2 | 2 | 3 | 1 |
6 | 2 | 3 | 1 | 2 |
7 | 3 | 1 | 3 | 2 |
8 | 3 | 2 | 1 | 3 |
9 | 3 | 3 | 2 | 1 |
- 步骤3,把控件及其取值映射到正交表中:
用例号↓ | 字体 | 字形 | 字体颜色 | 字号 | 预期结果 | 是否提bug |
---|---|---|---|---|---|---|
1 | 仿宋 | 常规 | 红色 | 12 | ||
2 | 仿宋 | 加粗 | 绿色 | 14 | ||
3 | 仿宋 | 倾斜 | 蓝色 | 16 | ||
4 | 黑体 | 常规 | 绿色 | 16 | ||
5 | 黑体 | 加粗 | 蓝色 | 12 | ||
6 | 黑体 | 倾斜 | 红色 | 14 | ||
7 | 楷体 | 常规 | 蓝色 | 14 | ||
8 | 楷体 | 加粗 | 红色 | 16 | ||
9 | 楷体 | 倾斜 | 绿色 | 12 |
依次类推,把映射好的正交排列表中的每一行,转换成一条测试用例。
这是进行测试的最少组合数量,但是,在测试中有72种(81-9)组合没有测试到。当然,如果时间允许,应该再补充一些用例。因为遗漏的组合越多,存在缺陷的可能性就越大。(时间问题!内测、公测)
示例2:114系统查询企业单位
我们再来看一个示例,114系统查询企业单位。
由上图可以发现,有5个因素,每个因素有个两个水平:
- 音形码:填(1)、不填(1)
- 拼音码:填(1)、不填(1)
- 路名码:填(1)、不填(1)
- 行业类别:填(1)、不填(1)
- 特征码:填(1)、不填(1)
手动整理一下:
编号 | 音形码 | 拼音码 | 路名码 | 行业类别 | 特征码 |
---|---|---|---|---|---|
1 | 填 | 填 | 填 | 填 | 填 |
2 | 不填 | 不填 | 不填 | 不填 | 不填 |
选择正交表:
- 表中的因素数>=5
- 每个因素数的水平数>=2
- 那么得到的公式就是
- 我们去查询正交表,会发现没有一个2的5次方的正交表,所以我们选择稍微大一级别的。
列号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
试验号 | |||||||
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
2 | 1 | 1 | 1 | 2 | 2 | 2 | 2 |
3 | 1 | 2 | 2 | 1 | 1 | 2 | 2 |
4 | 1 | 2 | 2 | 2 | 2 | 1 | 1 |
5 | 2 | 1 | 2 | 1 | 2 | 1 | 2 |
6 | 2 | 1 | 2 | 2 | 1 | 2 | 1 |
7 | 2 | 2 | 1 | 1 | 2 | 2 | 1 |
8 | 2 | 2 | 1 | 2 | 1 | 1 | 2 |
两个表都有了,我们建立映射关系:
列号 | 音形码 | 拼音码 | 路名码 | 行业类别 | 特征码 | 6 | 7 |
---|---|---|---|---|---|---|---|
1 | 填 | 填 | 填 | 填 | 填 | 1 | 1 |
2 | 填 | 填 | 填 | 不填 | 不填 | 2 | 2 |
3 | 填 | 不填 | 不填 | 填 | 填 | 2 | 2 |
4 | 填 | 不填 | 不填 | 不填 | 不填 | 1 | 1 |
5 | 不填 | 填 | 不填 | 填 | 不填 | 1 | 2 |
6 | 不填 | 填 | 不填 | 不填 | 填 | 2 | 1 |
7 | 不填 | 不填 | 填 | 填 | 不填 | 2 | 1 |
8 | 不填 | 不填 | 填 | 不填 | 填 | 1 | 2 |
至于多出来的两列,我们直接删掉就可以了。
混合正交表
使用正交法的局限性
- 目前常见的正交(排列)表只有前面介绍的几种。
- 即使是已有的正交表,基本都要求每个控件中取值的个数要相等,这在实际软件中很少遇到。
没有现成的正交排列表怎么办?
通过正交测试法的学习,我们更多的应该学习到一种测试思想,也就是在从所有组合集合中选取测试数据时,应该均匀的选取其中的组合作为测试用例,而不要只在某个局部选取数据。
而类似下面这种情况,也比较常见,我们利用之前的正交表,就不好使了:
体型 | 年龄段 | 性别 |
---|---|---|
胖 | 老人 | 男 |
适中 | 青年 | 女 |
瘦 | 儿童 |
如上的实例中,有三个因素(体型、年龄段、性别)。但各自的水平并不一致。这该怎么办?找不到现成的正交表。那只好用工具来生成了。
正交表生成工具allpairs
install allpairs
该软件下载参见:https://www.cnblogs.com/sundawei7/p/11947357.html
使用步骤
- 制作取值表(只列出数据即可,不用编号)
体型 | 年龄段 | 性别 |
---|---|---|
胖 | 老人 | 男 |
适中 | 青年 | 女 |
瘦 | 儿童 |
- 复制取值表的数据,保存到普通的(txt)文档中,比如t1.txt。注意,每个水平之间以tab做间隔,不要用空格,否则执行会报错:
Error: The first line of the file must be a tab-delimited list of labels with more than one label in it, and no blank labels.
- 将文本文件放在allpairs目录中。然后在该目录
Shift + 鼠标右键
打开命令行,在命令行中执行:
allpairs.exe t1.txt > t2.txt
allpairs.exe t1.txt > t3.xls
可以生成txt和Excel文件(在allpairs目录下),生成的文件就是我们想要的测试组合用例了。
用例 | 体型 | 年龄段 | 性别 |
---|---|---|---|
1 | 胖 | 老人 | 男 |
2 | 胖 | 青年 | 女 |
3 | 适中 | 老人 | 女 |
4 | 适中 | 青年 | 男 |
5 | 瘦 | 儿童 | 男 |
6 | 瘦 | 老人 | 女 |
7 | 胖 | 儿童 | 女 |
8 | 适中 | 儿童 | ~男 |
9 | 瘦 | 青年 | ~男 |
上例中的~男
表示填男填女不影响最终结果。
总结
介绍了这么几个测试方法。我们在实际的测试中,有的放矢的选择测试方法。
测试方法选择
通常在确定测试方法时,有以下几条参考原则:
- 拿到一个测试任务时,先关注它的主要功能和业务流程、业务逻辑是否正确实现,考虑使用场景法。
- 需要输入数据的地方,考虑采用等价类划分法,包括输入条件和输出条件的等价划分,将无限测试变成有限测试。
- 在任何情况下都必须采用边界值分析法。这种方法设计出的测试用例发现程序错误的能力最强。
- 如果程序的功能说明中含有输入条件的组合情况,则一开始就应考虑选用因果图和判定表法。
- 对于参数配置类的软件,需要考虑参数之间的组合情况,考虑使用正交排列法选择较少的组合方式(最少的测试用例获得最大的的测试覆盖率)。
- 对照程序逻辑,检查已设计出的测试用例的逻辑覆盖程度。如果没有达到要求的覆盖标准,则应当再补充更多的测试用例。
- 采用错误推断法再追加测试用例——依靠测试工程师的经验和智慧。