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个测试用例发现该缺陷,可以看出对于像三角形这类问题因为输入之间没有关联,单缺陷假设成立,所以没有必要使用最坏情况设计测试用例,健壮性测试可以获取边界外的测试结果。针对不同的问题要采用适合的不同策略。