5.5 举例分析
5.5.1 三角形问题的测试用例
回顾以下第2章中关于三角形的问题描述:三角形问题接受三个整数a、b、c作为输入,用做三角形的三条边。整数a、b、c必须满足以下条件:
C2: 1≤b≤200
C3: 1≤c≤200
C4:a﹤b+c
C5:b﹤a+c
C6:c﹤a+b
程序的输出是由这三条边确定的三角形类型:等边三角形、等腰三角形、不等边三角形或非三角形。如果输入值没有满足这些条件中的任何一个,则程序会通过输出消息来进行通知,例如,"b的取值不在允许取值的范围内。"如果a、b和c取值满足c1、c2和c3,则会给出以下四种相互排斥输出中的一个:
(1)如果三条边相等,则程序的输出是等边三角形。
(2)如果恰好有两条边相等,则程序输出的是等腰三角形。
(3)如果没有两条边相等,则程序输出的是不等边三角形。
(4)如果c4、c5和c6中有一个条件不满足,则程序输出的是非三角形。
测试用例设计
三角形输入下边界是1,上边界是200。
边界值分析测试用例:共4×3 + 1 = 13个,如下表所示
用例标识 | a | b | c | 预期输出 |
1 | 100 | 100 | 1 | 等腰三角形 |
2 | 100 | 100 | 2 | 等腰三角形 |
3 | 100 | 100 | 100 | 等边三角形 |
4 | 100 | 100 | 199 | 等腰三角形 |
5 | 100 | 100 | 200 | 非三角形 |
6 | 100 | 1 | 100 | 等腰三角形 |
7 | 100 | 2 | 100 | 等腰三角形 |
8 | 100 | 100 | 100 | 等边三角形 |
9 | 100 | 199 | 100 | 等腰三角形 |
10 | 100 | 200 | 100 | 非三角形 |
11 | 1 | 100 | 100 | 等腰三角形 |
12 | 2 | 100 | 100 | 等腰三角形 |
13 | 100 | 100 | 100 | 等边三角形 |
14 | 199 | 100 | 100 | 等腰三角形 |
15 | 200 | 100 | 100 | 非三角形 |
边界健壮性测试用例:共6×3 + 1 = 19个,如下表所示
用例标识 | a | b | c | 预期输出 |
1 | 100 | 100 | 0 | |
2 | 100 | 100 | 1 | 等腰三角形 |
3 | 100 | 100 | 2 | 等腰三角形 |
4 | 100 | 100 | 100 | 等边三角形 |
5 | 100 | 100 | 199 | 等腰三角形 |
6 | 100 | 100 | 200 | 非三角形 |
7 | 100 | 100 | 201 | 提示输入超出范围 |
8 | 100 | 0 | 100 | 提示输入超出范围 |
9 | 100 | 1 | 100 | 等腰三角形 |
10 | 100 | 2 | 100 | 等腰三角形 |
11 | 100 | 100 | 100 | 等边三角形 |
12 | 100 | 199 | 100 | 等腰三角形 |
13 | 100 | 200 | 100 | 非三角形 |
14 | 100 | 201 | 100 | 提示输入超出范围 |
15 | 0 | 100 | 100 | 提示输入超出范围 |
16 | 1 | 100 | 100 | 等腰三角形 |
17 | 2 | 100 | 100 | 等腰三角形 |
18 | 100 | 100 | 100 | 等边三角形 |
19 | 199 | 100 | 100 | 等腰三角形 |
20 | 200 | 100 | 100 | 非三角形 |
21 | 201 | 100 | 100 | 提示输入超出范围 |
最坏情况测试用例:共53 = 125个,如下表所示
用例标识 | a | b | c | 预期输出 |
1 | 1 | 1 | 1 | 等边三角形 |
2 | 1 | 1 | 2 | 非三角形 |
3 | 1 | 1 | 100 | 非三角形 |
4 | 1 | 1 | 199 | 非三角形 |
5 | 1 | 1 | 200 | 非三角形 |
6 | 1 | 2 | 1 | 非三角形 |
7 | 1 | 2 | 2 | 等腰三角形 |
8 | 1 | 2 | 100 | 非三角形 |
9 | 1 | 2 | 199 | 非三角形 |
10 | 1 | 2 | 200 | 非三角形 |
11 | 1 | 100 | 1 | 非三角形 |
12 | 1 | 100 | 2 | 非三角形 |
13 | 1 | 100 | 100 | 等腰三角形 |
14 | 1 | 100 | 199 | 非三角形 |
15 | 1 | 100 | 200 | 非三角形 |
16 | 1 | 199 | 1 | 非三角形 |
17 | 1 | 199 | 2 | 非三角形 |
18 | 1 | 199 | 100 | 非三角形 |
19 | 1 | 199 | 199 | 等腰三角形 |
20 | 1 | 199 | 200 | 非三角形 |
21 | 1 | 200 | 1 | 非三角形 |
22 | 1 | 200 | 2 | 非三角形 |
23 | 1 | 200 | 100 | 非三角形 |
24 | 1 | 200 | 199 | 非三角形 |
25 | 1 | 200 | 200 | 等腰三角形 |
26 | 2 | 1 | 1 | 非三角形 |
27 | 2 | 1 | 2 | 等腰三角形 |
28 | 2 | 1 | 100 | 非三角形 |
29 | 2 | 1 | 199 | 非三角形 |
30 | 2 | 1 | 200 | 非三角形 |
31 | 2 | 2 | 1 | 等腰三角形 |
32 | 2 | 2 | 2 | 等边三角形 |
33 | 2 | 2 | 100 | 非三角形 |
34 | 2 | 2 | 199 | 非三角形 |
35 | 2 | 2 | 200 | 非三角形 |
36 | 2 | 100 | 1 | 非三角形 |
37 | 2 | 100 | 2 | 非三角形 |
38 | 2 | 100 | 100 | 等腰三角形 |
39 | 2 | 100 | 199 | 非三角形 |
40 | 2 | 100 | 200 | 非三角形 |
41 | 2 | 199 | 1 | 非三角形 |
42 | 2 | 199 | 2 | 非三角形 |
43 | 2 | 199 | 100 | 非三角形 |
44 | 2 | 199 | 199 | 等腰三角形 |
45 | 2 | 199 | 200 | 不等边三角形 |
46 | 2 | 200 | 1 | 非三角形 |
47 | 2 | 200 | 2 | 非三角形 |
48 | 2 | 200 | 100 | 非三角形 |
49 | 2 | 200 | 199 | 不等边三角形 |
50 | 2 | 200 | 200 | 等腰三角形 |
51 | 100 | 1 | 1 | 非三角形 |
52 | 100 | 1 | 2 | 非三角形 |
53 | 100 | 1 | 100 | 等腰三角形 |
54 | 100 | 1 | 199 | 非三角形 |
55 | 100 | 1 | 200 | 非三角形 |
56 | 100 | 2 | 1 | 非三角形 |
57 | 100 | 2 | 2 | 非三角形 |
58 | 100 | 2 | 100 | 等腰三角形 |
59 | 100 | 2 | 199 | 非三角形 |
60 | 100 | 2 | 200 | 非三角形 |
61 | 100 | 100 | 1 | 等腰三角形 |
62 | 100 | 100 | 2 | 等腰三角形 |
63 | 100 | 100 | 100 | 等边三角形 |
64 | 100 | 100 | 199 | 等腰三角形 |
65 | 100 | 100 | 200 | 非三角形 |
66 | 100 | 199 | 1 | 非三角形 |
67 | 100 | 199 | 2 | 非三角形 |
68 | 100 | 199 | 100 | 等腰三角形 |
69 | 100 | 199 | 199 | 等腰三角形 |
70 | 100 | 199 | 200 | 不等边三角形 |
71 | 100 | 200 | 1 | 非三角形 |
72 | 100 | 200 | 2 | 非三角形 |
73 | 100 | 200 | 100 | 非三角形 |
74 | 100 | 200 | 199 | 不等边三角形 |
75 | 100 | 200 | 200 | 等腰三角形 |
76 | 199 | 1 | 1 | 非三角形 |
77 | 199 | 1 | 2 | 非三角形 |
78 | 199 | 1 | 100 | 非三角形 |
79 | 199 | 1 | 199 | 等腰三角形 |
80 | 199 | 1 | 200 | 非三角形 |
81 | 199 | 2 | 1 | 非三角形 |
82 | 199 | 2 | 2 | 非三角形 |
83 | 199 | 2 | 100 | 非三角形 |
84 | 199 | 2 | 199 | 等腰三角形 |
85 | 199 | 2 | 200 | 不等边三角形 |
86 | 199 | 100 | 1 | 非三角形 |
87 | 199 | 100 | 2 | 非三角形 |
88 | 199 | 100 | 100 | 等腰三角形 |
89 | 199 | 100 | 199 | 等腰三角形 |
90 | 199 | 100 | 200 | 不等边三角形 |
91 | 199 | 199 | 1 | 等腰三角形 |
92 | 199 | 199 | 2 | 等腰三角形 |
93 | 199 | 199 | 100 | 等腰三角形 |
94 | 199 | 199 | 199 | 等边三角形 |
95 | 199 | 199 | 200 | 等腰三角形 |
96 | 199 | 200 | 1 | 非三角形 |
97 | 199 | 200 | 2 | 不等边三角形 |
98 | 199 | 200 | 100 | 不等边三角形 |
99 | 199 | 200 | 199 | 等腰三角形 |
100 | 199 | 200 | 200 | 等腰三角形 |
101 | 200 | 1 | 1 | 非三角形 |
102 | 200 | 1 | 2 | 非三角形 |
103 | 200 | 1 | 100 | 非三角形 |
104 | 200 | 1 | 199 | 非三角形 |
105 | 200 | 1 | 200 | 等腰三角形 |
106 | 200 | 2 | 1 | 非三角形 |
107 | 200 | 2 | 2 | 非三角形 |
108 | 200 | 2 | 100 | 非三角形 |
109 | 200 | 2 | 199 | 不等边三角形 |
110 | 200 | 2 | 200 | 等腰三角形 |
111 | 200 | 100 | 1 | 非三角形 |
112 | 200 | 100 | 2 | 非三角形 |
113 | 200 | 100 | 100 | 非三角形 |
114 | 200 | 100 | 199 | 不等边三角形 |
115 | 200 | 100 | 200 | 等腰三角形 |
116 | 200 | 199 | 1 | 非三角形 |
117 | 200 | 199 | 2 | 不等边三角形 |
118 | 200 | 199 | 100 | 不等边三角形 |
119 | 200 | 199 | 199 | 等腰三角形 |
120 | 200 | 199 | 200 | 等腰三角形 |
121 | 200 | 200 | 1 | 等腰三角形 |
122 | 200 | 200 | 2 | 等腰三角形 |
123 | 200 | 200 | 100 | 等腰三角形 |
124 | 200 | 200 | 199 | 等腰三角形 |
125 | 200 | 200 | 200 | 等边三角形 |
测试程序源码及执行结果
- 测试程序设计
为了便于进行自动化测试对第2章的程序3进行简单的改造,改造如下:
(1)对于输入判断函数input,接收3个输入,如果输入符合要求(C1、C2、C3)返回0,否则返回-1;
(2)对于判断是不是三角形函数isTriangle,接收三个输入,如果判断满足是三角形的条件(C4、C5、C6)返回0,否则返回-1;
(3)对于判断三角形类型函数typeTriangle,接收三个输入,返回值为-1表示输入不满足要求、1非三角形、2表示不等边三角形(普通三角形)、3表示等腰三角形、4表示等边三角形。
测试用例使用csv格数文件存储,格式如下:
第一列为用例序号,第二、三、四列为3条边的值,第五列为预期结果。
测试程序从数据文件获取数据,执行三角形判断程序(被测程序),获取执行结果,并与预期结果进行比较,判断测试结果,给出测试结论。
源程序如下:
#include <stdio.h>
#include <string.h>
int input(int a, int b, int c)
{
int c1, c2, c3;
c1 = (1 <= a) && (a <= 200);
c2 = (1 <= b) && (b <= 200);
c3 = (1 <= c) && (c <= 200);
if (c1 == 0)
{
//printf("Value of a is not in the range of permitted values.\n");
return -1;
} else if (c2 == 0)
{
//printf("Value of b is not in the range of permitted values.\n");
return -1;
} else if (c3 == 0)
{
//printf("Value of c is not in the range of permitted values.\n");
return -1;
} else
{
/*
printf("Side A is %d.\n", a);
printf("Side B is %d.\n", b);
printf("Side C is %d.\n", c);*/
return 0;
}
}
int isTriangle(int a, int b, int c)
{
if ((a<b+c) && (b<a+c) && (c<a+b))
{
return 0;
}
else
{
return -1;
}
}
/*
进行三角形判断
参数a,b,c分别是三条边的长度
返回值:
-1 表示 输入不满足
C1:1≤a≤200
C2: 1≤b≤200
C3: 1≤c≤200
1 表示 不是三角形
2 表示 不等边三角形,普通三角形
3 表示 等腰三角形
4 表示 等边三角形
*/
int typeTriangle(int a, int b, int c)
{
int retInput;
retInput = input(a, b, c);
//输入不满足要求,返回-1
if (retInput == -1)
{
//printf("a, b or c <1 or >200.\n");
return -1;
}
//判断是不是三角形
int bTriangle = isTriangle(a, b, c);
if (bTriangle == -1)
{
//printf("Not a triangle.\n");
return 1;
}
if ((a == b) && (b == c))
{
//printf("Equilateral triangle.\n");
return 4;
}
else if ((a != b) && (a != c) && (b != c))
{
//printf("Scalene triangle.\n");
return 2;
}
else
{
//printf("Isosceles triangle.\n");
return 3;
}
}
int main(void)
{
FILE *fp;
char exp[18];
int tcId, a, b, c;
int retScan;
fp = fopen("d:\\softwareTesting\\triBoundary.csv", "r");
//fp = fopen("d:\\softwareTesting\\triR.csv", "r");
//fp = fopen("d:\\softwareTesting\\tri125.csv", "r");
int retType = -1;//返回的三角形类型
int strCompare = -1;//字符串比较结果
if (fp != NULL)
{
printf("Open data.csv success.\n");
//fscanf(fp, "%d,%d", &tcId, &a);
//printf("%d,%d\n",tcId,a);
printf(" TcId a b c 预期结果 实际结果 结论\n");
printf("-----------------------------------------------------\n");
retScan = fscanf(fp, "%d,%d,%d,%d,%s,exp",&tcId,&a,&b,&c,exp);
while(retScan == 5)
{
printf("%4d %4d %4d %4d %12s ",tcId,a,b,c,exp);
//printf("retScan = %d,", retScan);
retType = typeTriangle(a, b, c);
//printf("retType = %d\n", retType);
switch (retType)
{
case -1:
printf(" 输入超出范围");
strCompare = strcmp(exp, "输入超出范围");
if (strCompare == 0)
printf(" √\n");
else
printf(" ×\n");
break;
case 1:
printf(" 非三角形");
strCompare = strcmp(exp, "非三角形");
if (strCompare == 0)
printf(" √\n");
else
printf(" ×\n");
break;
case 2:
printf(" 不等边三角形");
strCompare = strcmp(exp, "不等边三角形");
if (strCompare == 0)
printf(" √\n");
else
printf(" ×\n");
break;
case 3:
printf(" 等腰三角形");
strCompare = strcmp(exp, "等腰三角形");
if (strCompare == 0)
printf(" √\n");
else
printf(" ×\n");
break;
case 4:
printf(" 等边三角形");
strCompare = strcmp(exp, "等边三角形");
if (strCompare == 0)
printf(" √\n");
else
printf(" ×\n");
break;
default:
printf(" 其它情况");
printf(" ×\n");
break;
}
retScan = fscanf(fp, "%d,%d,%d,%d,%s,exp",&tcId,&a,&b,&c,exp);
}
fclose(fp);
}
else
{
printf("Open data.csv fail.\n");
}
return 1;
}
边界值分析测试用例执行结果如下:
边界健壮性测试用例:
最坏情况测试用例片段如下:
发现缺陷的能力:
设定程序存在一处缺陷:边c的上边界判断少了一个“=”
……
c1 = (1 <= a) && (a <= 200);
c2 = (1 <= b) && (b <= 200);
c3 = (1 <= c) && (c < 200);
……
三个方法发现缺陷如下:
边界值分析测试用例执行结果如下:有一个测试用例发现该缺陷。
边界健壮性测试用例:有一个测试用例发现该缺陷。
最坏情况测试用例片段如下:共有25个测试用例发现该缺陷,冗余较大。
总结:
三种方法都可发现该缺陷,边界值分析方法和健壮性方法都有一个测试用例发现该缺陷,最坏情况有25个测试用例发现该缺陷,可以看出对于像三角形这类问题因为输入之间没有关联,单缺陷假设成立,所以没有必要使用最坏情况设计测试用例,健壮性测试可以获取边界外的测试结果。针对不同的问题要采用适合的不同策略。