一、问题
想必每个tester都有测试过类似下图中需要组合多种元素的业务场景,当然我们不会把所有条件元素组合的可能性都覆盖一遍,而是采取正交实验法进行用例设计,可以在不影响业务场景覆盖的前提下大大减少用例数量,既保证用例质量又降低测试时间成本。
以上图为例:
性别:男、女
班级:一年级、二年级、三年级、四年级、五年级
年龄区间:8岁以下、8-10岁、10-13岁
在正交实验法中,性别、班级、年龄区间这三个被测元素称为 因素,每个因素的取值称之为水平值。
如果全量测试场景下:测试用例数量=2*5*3=30(个)。正交实验法数量远远少于全量测试用例数量,当然正交实验法原理稍微复杂,我们直接使用现成的工具生成测试用例即可。今天介绍的工具就是一个Python库:allpairspy。
二、allpairspy实践
1. 基础用法
以上述测试场景为例,咱们利用工具生成测试用例。
代码语言:javascript复制from allpairspy import AllPairs
parameters = [
["男", "女"],
["一年级", "二年级", "三年级", "四年级", "五年级"],
["8岁以下", "8-10岁", "10-13岁"]
]
print("PAIRWISE:")
for i, pairs in enumerate(AllPairs(parameters)):
print("用例编号{:2d}: {}".format(i, pairs))
哇哈,是不是很惊喜,少了一半,也就是说降低一半的测试成本。
2. 过滤
当然有些因素之间值的组合是无效的,这时候可以通过在AllPairs构造函数中设置过滤函数filter_func来过滤这些无效用例组。咱们举个例子:年龄区间取值10-13岁不可能对应一年级学生。
代码语言:javascript复制from allpairspy import AllPairs
def is_valid_combination(row):
n = len(row)
# 设置过滤条件
if n > 2:
# 一年级 不能匹配 10-13岁
if "一年级" == row[1] and "10-13岁" == row[2]:
return False
return True
parameters = [
["男", "女"],
["一年级", "二年级", "三年级", "四年级", "五年级"],
["8岁以下", "8-10岁", "10-13岁"]
]
print("PAIRWISE:")
for i, pairs in enumerate(AllPairs(parameters, filter_func=is_valid_combination)):
print("用例编号{:2d}: {}".format(i, pairs))
很好,将不符合条件的用例直接过滤掉。
3. OrderedDict
如果你想用例更一目了然,使用OrderedDict,可以将结果存储到nametuple数据结构中。
代码语言:javascript复制from collections import OrderedDict
from allpairspy import AllPairs
parameters = OrderedDict({
"性别": ["男", "女"],
"年级": ["一年级", "二年级", "三年级", "四年级", "五年级"],
"年龄区间": ["8岁以下", "8-10岁", "10-13岁"]
})
print("PAIRWISE:")
for i, pairs in enumerate(AllPairs(parameters)):
print("用例编号{:2d}: {}".format(i, pairs))
4. 结合pytest
更强大的是,如果你要进行单测或者接口测试,它还可以结合测试框架pytest让你的测试更高效,将生成的组合数据通过数据驱动的方式传递给待测函数/接口。示例如下。
代码语言:javascript复制import pytest
from allpairspy import AllPairs
def function_to_be_tested( sex, grade, age):
if grade == "一年级" and age == "10-13岁":
return False
return True
class TestParameterized(object):
@pytest.mark.parametrize(["sex", "grade", "age"], [
value_list for value_list in AllPairs([
[u"男", u"女"],
["一年级", "二年级", "三年级", "四年级", "五年级"],
["8岁以下", "8-10岁", "10-13岁"]
])
])
def test(self, sex, grade, age):
assert function_to_be_tested(sex, grade, age)
⚠️ 结果中没做中文转码,自动忽略。
三、总结
组合参数测试往往是比较枯燥的,借助allpairspy可以快速生成高质量的测试用例,快捷又高效,希望每个tester都能掌握这个工具,多在项目中使用它降低测试成本。