如何使用集合的组合作为测试数据
-
08-06-2019 - |
题
我想用一组边缘情况和正常值的元组来测试一个函数。例如,在测试返回的函数时 true
每当给定形成有效三角形的三个长度时,我都会遇到特定情况,负数/小数/大数,接近溢出的值等;更重要的是,主要目标是生成这些值的组合, 和 或者 没有 重复,以获得一组测试数据。
(inf,0,-1), (5,10,1000), (10,5,5), (0,-1,5), (1000,inf,inf),
...
作为注释:我实际上知道这个问题的答案,但这可能对其他人有帮助,对这里的人来说也是一个挑战!——稍后会发布我的答案。
解决方案
当然,特别是处理大量这些排列/组合时,我绝对可以看到第一遍将是一个问题。
尽管我根据“算法 515”用 C 和 Ocaml 编写了一个很好的实现(见下文),但 Python 中的实现很有趣。他用 Fortran 语言编写了他的论文,因为当时所有“算法 XX”论文都很常见,嗯,那个汇编或 c。我必须重新编写它并进行一些小的改进才能处理数组而不是数字范围。这个是随机访问的,我仍在努力获得 Knuth 第 4 卷第 2 卷中提到的一些不错的实现。我将向读者解释这是如何工作的。不过,如果有人好奇,我不会反对写一些东西。
/** [combination c n p x]
* get the [x]th lexicographically ordered set of [p] elements in [n]
* output is in [c], and should be sizeof(int)*[p] */
void combination(int* c,int n,int p, int x){
int i,r,k = 0;
for(i=0;i<p-1;i++){
c[i] = (i != 0) ? c[i-1] : 0;
do {
c[i]++;
r = choose(n-c[i],p-(i+1));
k = k + r;
} while(k < x);
k = k - r;
}
c[p-1] = c[p-2] + x - k;
}
~”算法 515:从词典索引生成向量”;巴克斯,B.P.,和莱巴农,M.ACM 数学软件汇刊,卷。3、没有。2、1977 年 6 月。
其他提示
使用全新的 Python 2.6,您将拥有一个带有 itertools 模块的标准解决方案,该模块返回 iterables 的笛卡尔积:
import itertools
print list(itertools.product([1,2,3], [4,5,6]))
[(1, 4), (1, 5), (1, 6),
(2, 4), (2, 5), (2, 6),
(3, 4), (3, 5), (3, 6)]
您可以提供一个“重复”参数来执行可迭代和自身的乘积:
print list(itertools.product([1,2], repeat=3))
[(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2),
(2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)]
您还可以通过组合来调整一些内容:
print list(itertools.combinations('123', 2))
[('1', '2'), ('1', '3'), ('2', '3')]
如果顺序很重要,则有排列:
print list(itertools.permutations([1,2,3,4], 2))
[(1, 2), (1, 3), (1, 4),
(2, 1), (2, 3), (2, 4),
(3, 1), (3, 2), (3, 4),
(4, 1), (4, 2), (4, 3)]
当然,所有这些很酷的东西并不完全相同,但您可以以某种方式使用它们来解决您的问题。
请记住,您可以使用 list()、tuple() 和 set() 将元组或列表转换为集合,反之亦然。
有趣的问题!
我会通过选择组合来做到这一点,类似于 python 中的以下内容。最难的部分可能是首次通过验证,即 if f(1,2,3) returns true
, ,这是正确的结果吗?一旦验证了这一点,这就是回归测试的良好基础。
制作一组您知道全部正确的测试用例可能是个好主意(例如3,4,5(对于这个三角形情况),以及一组您知道将全部错误的测试用例(例如0,1,无穷)。然后您可以更轻松地验证测试是否正确。
# xpermutations from http://code.activestate.com/recipes/190465 from xpermutations import * lengths=[-1,0,1,5,10,0,1000,'inf'] for c in xselections(lengths,3): # or xuniqueselections print c
(-1,-1,-1); (-1,-1,0); (-1,-1,1); (-1,-1,5); (-1,-1,10); (-1,-1,0); (-1,-1,1000); (-1,-1,inf); (-1,0,-1); (-1,0,0); ...
我认为你可以用 行测试属性 (在 MbUnit 和更高版本的 NUnit 中可用),您可以在其中指定多个集合来填充一个单元测试。
虽然可以创建大量测试数据并看看会发生什么,但尝试最小化所使用的数据会更有效。
从典型的 QA 角度来看,您可能希望识别不同的输入分类。为每个分类生成一组输入值并确定适当的输出。
这是输入值类别的示例
- 具有较小数字的有效三角形,例如 (10 亿, 2, 10 亿, 20 亿)
- 具有大数字的有效三角形,例如 (0.000001, 0.00002, 0.00003)
- “几乎”平坦的有效钝角三角形,例如 (10, 10, 19.9999)
- “几乎”平坦的有效锐角三角形,例如 (10, 10, 0000001)
- 至少有一个负值的无效三角形
- 两条边之和等于第三条边的无效三角形
- 两条边之和大于第三条边的无效三角形
- 输入非数字值
...
一旦您对此函数的输入分类列表感到满意,就可以创建实际的测试数据。测试每个项目的所有排列可能会有所帮助。(例如。(2,3,4), (2,4,3), (3,2,4), (3,4,2), (4,2,3), (4,3,2)) 通常,你会发现你错过了一些分类(例如 inf 作为输入参数的概念)。
一段时间内的随机数据也可能有帮助,可以发现代码中的奇怪错误,但通常效率不高。
更有可能的是,此函数正在应用附加规则的某些特定上下文中使用。(例如仅整数值或值必须以 0.01 为增量,等等。)这些将添加到输入参数的分类列表中。