软件测试的方法应该建立在不同的软件测试类型上,不同的测试类型会存在不同的方法。本文以软件测试中常见的黑盒测试为例,简述常见软件测试方法。
黑盒测试用例设计方法包括等价类划分法、边界值分析法、因果图法、判定表驱动法、正交试验设计法、场景法、功能分解法、功能图法、错误推测法等。
等价类划分法就是把需要测试的软件的输入值(输入域)划分为若干部分(子集或等价类),然后在这若干部分中取出少量的数据作为测试数据,每一类的代表性数据在测试中的作用等价于这一类中的其他值。
例如:输入值是学生成绩,范围是0~100,那么对于这个学生成绩的等价类就可以按照如下规则划分
在针对上述的方法,从这些等价类中取出部分少量数据作为测试数据,就可以设计出三个测试用例:
输入成绩60(有效等价类),期待成功
输入成绩-10(无效等价类1),期待失败
输入成绩120(无效等价类2),期待失败
采用等价类划分法设计的这三条用例的结果,就可以作为整个输入值(0~100)的测试结果。
但是实际情况中,并不会采用单一的测试方法来对测试结果进行判断,会采用许多方法,做一个综合的判断。
边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法。是作为对等价类划分法的补充,其测试用例来自等价类的边界。
很多错误是发生在输入或输出范围的边界上,而不是中间区域。因此针对各种边界情况设计测试用例,可以查出更多的错误。
例如针对上述学生成绩的例子,就可以得到一些特殊的边界值用例:
输入成绩-1
输入成绩0
输入成绩1
输入成绩99
输入成绩100
输入成绩101
这几个数值都属于边界条件值。
因果图法是一种利用图解分析输入与输出的各种组合情况,从而设计测试用例的方法,它适合于检查程序输入条件的各种组合情况。
等价类划分法和边界值分析法都是着重考虑输入条件,但没有考虑输入条件的组合以及制约关系。如果在测试时必须考虑输入条件的各种组合,那组合的数目可能是天文数字,所以必须考虑采用一种合适的方法对条件组合进行分析,简化。最终目的是用最少的测试用例覆盖最全面的场景。
因果图中的基本符号有四种,分别是恒等 (—) 、或 (~) 、与 (V) 、非(^)。
恒等:原因和结果都只能取 2 个值,1 代表条件成立,0 代表条件不成立。恒等相当于原因成立,则结果出现;若原因不成立,则结果也不出现。恒等关系“—”来表示。
非:原因和结果相反。若原因成立,则结果不出现;若原因不成立,则结果出现。非的关系用 “ ~ ” 表示。
或:有多个原因。若几个原因中有一个成立,则结果出现;若几个原因都不成立,则结果不出现。或的关系用 “ V ” 来表示。
与:有多个原因。只有几个原因都成立,结果才或出现;若其中一个原因不成立,则结果不出现。与的关系用 “ ^ ” 来表示。
因果图中四种基本约束条件分别是:互斥、包含、唯一、要求。
互斥 E:a、b、c 只能有一个成立,但是可以都不成立。
包含 I:a、b、c 中至少有一个成立。可以多选但不能不选。
唯一 O:a、b、c 有且仅有一个为 1。也就是说多个原因中有且只有一个成立。
要求 R:如果 a 成立,则要求 b 必须也成立,其他的不做约束。一个出现,另一个也一定出现
找出所有的原因,原因即输入条件或输入条件的等价类。
找出所有的结果,结果即输出条件。
明确所有输入条件之间的制约关系以及组合关系,判断条件是否可以组合。
明确所有输出条件之间的制约关系以及组合关系,判断结果是否可以同时输出。
找出不同输入条件组合会产生哪些输出结果。
将因果图转换成判定表或决策树。
根据判定表或决策表中每一列表示的情况设计测试用例。
需求:交通一卡通自动充值软件系统。系统只接收 50 或 100 元纸币,一次只能使用一张纸币,一次的充值金额只能为 50 或 100 元。
明确输入的条件为:
选择投币 50 元
选择投币 100 元
选择充值 50 元
选择充值 100 元
明确输出的结果为:
a.完成充值、退卡
b.提示充值成功
c.找零
d.提示错误
上文的输入条件:
选择投币 50 元
选择投币 100 元
选择充值 50 元
选择充值 100 元
分析得到的输入条件的因果图:
其中,输入条件的1和2因为每次只能使用一张纸币的限制,所以是互斥关系。3和4同理。
可以组合的输入条件:
条件 1 和 3 可以同时成立
条件 1 和 4 可以同时成立
条件 2 和 3 可以同时成立
条件 2 和 4 可以同时成立
条件 1 2 3 4 可以单独出现
上文输出的结果:
a.完成充值、退卡
b.提示充值成功
c.找零
d.提示错误
分析得到输出条件的因果图:
可以组合的输出结果:
输出 a 和 b 一定会同时出现(要求)
输出 a、b、c可以同时出现
输出 c、d可以同时出现
输出 d 单独存在。
首先,从上文中的可以组合的输入条件进行判断:
条件 1 和 3 可以同时成立,也就是选择投币50和选择充值50,那么就会得到两个结果,也就是完成充值,退卡以及提示充值成功:
条件 1 和 4 可以同时成立,也就是选择投币50和选择充值100,也会得到两个结果,也就是找零以及提示错误,因为投币50不能充值100
条件 2 和 3 可以同时成立,也就是选择投币100和选择充值50,会得到三个结果,完成充值,退卡、提示充值成功以及找零
条件 2 和 4 可以同时成立,也就是选择投币100和选择充值100,会得到两个结果,完成充值退卡以及提示充值成功。
条件 1 2 3 4 可以单独出现
条件1:只投入50,未选择充值金额,会导致退币,充值失败
条件2:只投入100,未选择充值金额,会导致退币,充值失败
条件3:只选择充值50,不投币,会导致充值失败
条件4:只选择充值100,不投币,会导致充值失败
本图为简略版,具体关于判定表的使用见下文。
根据上述表格内容编写测试用例,判定表和因果图已经十分明确了,这里就不过多赘述。
在因果图分析法中最后会得出一个判定表,可以看出因果图和判定表是有联系的,一般需要结合起来使用。
因果图是一种分析工具,通过分析最终得到判定表,再通过判定表编写测试用例。在一定情况下也可以直接书写判定表,省略因果图,进而编写测试用例。
判定表是由条件桩、动作桩、条件项和动作项组成的。条件桩表示可能出现这个问题的所有条件,动作桩表示这个问题的所有输出结果,条件项为条件桩的取值,动作项为条件项的各个取值情况下的输出结果。
设计判定表首先需要列出所有的条件桩和动作桩,确定规则数量,规则数由条件桩确定,规则数 = 条件取值数 ^ 条件数。
依次填入条件项和动作项得到初始判定表。初始判定表会包含冗余的内容,这些内容一般不适合设计测试用例,进一步的简化判定表,合并相似的规则或动作得到一个完整并且简洁的判定表便于最终设计用例。
需求:输入三个正整数a、b、c,分别作为三角形的三条边,判断三条边是否能构成三角形,如果能构成三角形,判断三角形的类型。
确定条件桩
C1:a,b,c 构成三角形?a<b+c、b<a+c、c<a+b
C2:a = b?
C3:a = c?
C4:b = c?
确定动作桩
A1:非三角形
A2:不等边三角形
A3:等腰三角形
A4:等边三角形
A5:不可能
填写表格,确定条件项和动作项 确定规则数 共有四个条件,每个条件的取值为 “ 是 ” 或 “ 否 ”,因此有 2 ^ 4 = 16 条规则。
设计判定表
C1:8 个 0,8 个 1;
C2:4 个 0,4 个 1,4 个 0,4 个 1;
C3:2 个 0,2 个 1,2 个 0,2 个 1,2 个 0,2 个 1,2 个 0,2个1;
C4:0,1,0,1,0,1,0,1,0,1...
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | |
条件桩 | ||||||||||||||||
是否三角形? | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
a = b? | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
a = c? | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
b = c? | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
动作桩 | ||||||||||||||||
非三角形 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||||||||
不等边三角形 | 1 | |||||||||||||||
等腰三角形 | 1 | 1 | 1 | |||||||||||||
等边三角形 | 1 | 1 | ||||||||||||||
不可能 | 1 | 1 |
简化判定表
构成三角形的条件如果不满足的话,结果都是非三角形,和下面三个条件无关,这种情况下可以对判定表进行简化。
条件桩 | ||||||
是否三角形? | 0 | 1 | 1 | 1 | 1 | 1 |
a = b? | 0 | 0 | 0 | 1 | 1 | |
a = c? | 0 | 0 | 1 | 0 | 1 | |
b = c? | 0 | 1 | 0 | 0 | 1 | |
动作桩 | ||||||
非三角形 | 1 | |||||
不等边三角形 | 1 | |||||
等腰三角形 | 1 | 1 | 1 | |||
等边三角形 | 1 | |||||
不可能 |
设计测试用例时不可能的情况可以排除,非三角形的情况需要考虑每个值取值的不同情况。得出最后的测试用例如下表所示:
一般用于在有限的试验次数内尽可能全面地测试系统的不同因素和参数组合情况。个人认为,叫做控制变量法比较通俗易懂。
例:我们正在测试一款电子产品的显示屏参数。我们想要测试不同的因素,如亮度、对比度和色彩饱和度。则:
对于亮度、对比度和色彩饱和度这三个因素,我们可以通过正交试验设计法生成以下试验表:
试验1:亮度高、对比度低、色彩饱和度低 试验2:亮度低、对比度高、色彩饱和度低 试验3:亮度低、对比度低、色彩饱和度高
其实,对于最正规(教学标准)来讲,场景法应该有如下步骤:
识别关键业务流程。需要确定系统的主要功能模块或业务流程,例如:在线购物中的商品浏览、加入购物车、结算支付、订单确认等。
构建基本流与备选流:
基本流(Basic Flow)是指按照正常预期顺序执行的一系列步骤,即最理想且常见的操作路径。
备选流(Alternative Flow)则涵盖了各种异常处理和分支逻辑,如登录失败、商品库存不足、支付过程中取消交易等。
创建详细场景:
对于每个关键流程,设计详细的场景描述,包括输入数据、触发事件、系统响应以及预期结果。
场景通常包含一系列动作序列,这些动作代表了从开始到结束的一个完整操作过程。
编写测试用例:
根据场景设计出具体的测试用例,确保覆盖基本流和所有重要的备选流。
测试用例应明确指出测试目标、前置条件、操作步骤、预期结果以及可能出现的边界条件或异常处理。
执行与验证。执行设计好的测试用例,与预期结果进行比较。
需求:使用场景法对在线银行系统“转账”功能进行测试
按照上述给的标准步骤,则:
转账流程有以下业务:
用户登录(在线银行需要登录)
输入转账金额和收款人信息
确认转账信息并提交
完成转账操作,显示转账结果
基本流:
用户成功登录后选择转账功能
输入正确的转账金额(满足最小转账额度且不超过账户余额)和有效正确的收款人账号信息
系统验证转账信息无误,扣款成功,向收款人账号转入资金,完成转账并展示转账成功的提示
备选流:
用户未登录或登录失败(账密错误 / 验证码错误 / 手机号错误等情况)
转账金额低于最低限额或超过账户余额
收款人账号信息无效或不存在
在线交易时网络连接中断或服务器故障
转账过程中账户余额被其他交易占用导致转账失败
用户在最后确认前取消转账操作
场景一(基本流):用户A有足够的资金从其账户向用户B成功转账
场景二(备选流):用户A尝试转账但输入的金额低于银行规定的最低转账额度,系统应给出错误提示
场景三(备选流):用户A的账户余额不足进行转账操作,系统提示账户余额不足以完成转账
场景四(备选流):用户A填写的收款人账号不存在,系统需验证并反馈错误信息
场景五(备选流):在转账过程中由于网络问题,交易未能及时完成,系统需要处理该异常情况,并在恢复连接后提供重新发起交易的选项
上述详细场景已经很明确了,关于具体的测试用例编写方法,会在后文详细讲解。
执行上述测试用例,将实际结果和预期比较,若发现问题则需上报。
功能分解法在软件测试中,通常用来将一个复杂的系统或功能模块拆分成一系列更小、更易于理解和处理的子功能。
例:现在需要测试一个简单的用户登录系统的功能,按照功能分解的思维对这个功能进行细分。
一级功能分解:
用户身份验证功能:
输入验证(检查用户名是否存在、密码格式是否正确等)
数据库查询(根据用户名查找对应的用户记录 / 检查后台的SQL是否有误)
密码匹配(比较输入的密码与数据库存储的密码是否一致)
会话管理(成功登录后创建用户会话 / 用户欢迎页,更新最后登录时间等信息)
用户界面展示与交互:
登录页面布局设计(包含用户名和密码输入框、登录按钮等)
错误提示反馈(如用户名不存在、密码错误等)
权限控制:
不同角色权限分配(管理员、普通用户等拥有不同的访问权限)
登录后的权限加载(登录成功后加载相应角色的权限设置)
二级功能分解(这里以一级功能分解中的“用户身份验证功能”为例):
输入验证:
用户名有效性验证(长度、字符类型等)
密码有效性验证(长度、复杂度要求等)
数据库操作:
连接数据库服务,最大连接数?一直占用不释放会如何处理连接池?
执行SQL查询语句
处理查询结果
SQL优化是否需要考虑?例如查询数据时间过长是否使用了让索引失效的SQL写法等
密码安全性处理:
密码加密算法应用
加密后的密码比对,是否容易被破解,泄漏?
对称加密、非对称加密、哈希加密等是否需要验证?
通过这样的逐级分解,每个小的功能块都可以独立进行测试,从而提高测试覆盖率,也能够对这个软件进行一个整体的把握。
功能图法是一种利用图形化工具来描述和分析系统的功能结构以及状态转换。
这种方法通过创建功能模型和状态迁移图,能够更好的理解系统的动态行为,并据此生成全面且有效的测试用例。
分析需求文档:了解系统的所有功能和业务规则
构建功能模型:将系统分解为多个功能模块并绘制功能关系图
绘制状态迁移图:对于具有多种状态和复杂交互逻辑的功能,定义所有可能的状态及状态间的迁移条件
生成测试用例:
对于功能模型,针对每个功能模块设计不同的输入和预期输出,确保覆盖所有重要的功能路径。
对于状态迁移图,依据每个状态及其变迁,确定需要测试的初始状态、中间状态和最终状态组合,包括正常情况下的状态迁移以及异常或边界条件下的状态变化
评审与优化:检查生成的测试用例是否覆盖了所有关键功能和状态迁移路径,对遗漏或冗余的部分进行补充或删除
基于经验和直觉推测程序中所有可能存在的各种错误, 从而有针对性的设计测试用例的方法。
特殊值测试:为了检查程序是否能够正确处理特殊值,可以选择一些边界值、极大值、极小值、空值等来进行测试。例如,对于一个计算器功能的程序,可以输入0作为入参,检查程序是否能够正确处理零作为除数的错误。
非法输入测试:故意输入一些非法的数据类型或格式,以检查程序是否能够正确处理并给出相应的错误提示。例如,对于一个要求输入数字的文本框,可以尝试输入字母、特殊字符等非法字符,检查程序是否能够正确处理错误。
历史数据测试:使用曾经出现过问题的数据来进行测试,以检查程序是否已经修复了之前的错误。例如,对于一个用户登录系统,可以使用曾经导致登录失败的用户名和密码进行测试,观察是否能够正常登录。
极端条件测试:模拟极端条件下的输入,如极大或极小的数值、极端的操作等,以检查程序是否能够正确处理并给出正确的结果。例如,对于一个计算运动轨迹的程序,可以输入极大或极小的速度和加速度进行测试,观察程序的计算结果是否合理。
这些都是容易发生错误的情况,可选择这些情况下的例子作为测试用例。