3. 小心卫哨(Guard)语句
许多软件用卫哨语句来“过滤”无效的输入。例如,在如下代码中,if语句会“过滤”掉所有A<=0的输入。
int func(int A, int B, int C) { if (A <= 0) return ERROR; ... } |
如果我没有读过代码,没有仔细分析规格说明,我可能会制定如下的模型文件。在该模型中,A的取值是-1, 0, 1。
A: -1, 0, 1 B: -1, 0, 1 C: -1, 0, 1 |
利用上述模型,所生成的测试用例集包含9条测试用例。
A B C 0 1 -1 1 -1 1 -1 0 -1 1 1 0 -1 -1 0 0 0 1 1 -1 -1 -1 1 1 0 -1 0 1 0 0 |
在这9条测试用例中,有6条测试用例会被if语句过滤掉,因为其中A<=0。只有3条测试用例,能够执行后续逻辑,这意味着只有1/3的B和C的取值组合被真正地覆盖。这个例子表明,如果忽视了卫哨语句对执行流的中断,组合测试用例集将不能达成两因素或多因素覆盖的目标 。
面对此类问题,测试人员要仔细阅读规格说明或源代码,发现会导致执行流中断的“负面”(Negative)取值。我通常将负面取值从模型中排除,将因素的取值置于正常执行流的范围。例如,对于上述被测试函数func,将模型文件定义为:
A: 1, 10, 100 B: -1, 0, 1 C: -1, 0, 1 |
在生成测试用例集之后,再加入一条的测试用例(A: 0,B: 0, C: 0)。原模型生成的测试用例可以“通过”卫哨语句,覆盖因素A、B、C的两两取值组合;附加的测试用例可以覆盖卫哨语句的“过滤”功能。
另一种方法,是在PICT的模型中,用特殊符号"~"标记出非法(invalid)值。例如,在如下模型中,参数A的取值0被标记为非法。
A: ~0, 1, 10 B: -1, 0, 1 C: -1, 0, 1 |
PICT会保证所有有效值的取值组合都会被覆盖,此外任意非法值与有效值的组合也会被覆盖。以上模型将生成如下测试用例集。
A B C 1 1 -1 1 0 1 10 -1 -1 1 -1 0 10 0 -1 10 -1 1 10 0 0 10 1 0 1 1 1 ~0 0 -1 ~0 -1 0 ~0 1 1 |