软件测试之黑盒测试
黑盒测试也称功能测试,它是通过测试来检测每个功能是否都能正常使用。在测试中,把程序看作一个不能打开的黑盒子,在完全不考虑程序内部结构和内部特性的情况下,在程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数据而产生正确的输出信息。
应用举例:
输入三边a,b,c,取值:[1,100],判断是否为三角形,为哪种类型的三角形(等边,等腰,直角,一般)。
要求:使用边界值分析、等价类测试、基于决策表的测试方法设计测试用例
设计测试用例
采用边界值分析,健壮性边界值分析设计测试用例如下:
一般边界值分析(4N+1) | ||||
---|---|---|---|---|
测试用例 | 边长a | 边长b | 边长c | 预期输出 |
Test1 | 50 | 50 | 1 | 等腰三角形 |
Test2 | 50 | 50 | 2 | 等腰三角形 |
Test3 | 50 | 50 | 50 | 等边三角形 |
Test4 | 50 | 50 | 99 | 等腰三角形 |
Test5 | 50 | 50 | 100 | 非三角形 |
Test6 | 50 | 1 | 50 | 等腰三角形 |
Test7 | 50 | 2 | 50 | 等腰三角形 |
Test8 | 50 | 99 | 50 | 等腰三角形 |
Test9 | 50 | 100 | 50 | 非三角形 |
Test10 | 1 | 50 | 50 | 等腰三角形 |
Test11 | 2 | 50 | 50 | 等腰三角形 |
Test12 | 99 | 50 | 50 | 等腰三角形 |
Test13 | 100 | 50 | 50 | 非三角形 |
健壮性边界值分析(6N+1,在一般基础上补充) | ||||
Test14 | 50 | 50 | 0 | 超出范围 |
Test15 | 50 | 50 | 101 | 超出范围 |
Test16 | 50 | 0 | 50 | 超出范围 |
Test17 | 50 | 101 | 50 | 超出范围 |
Test18 | 0 | 50 | 50 | 超出范围 |
Test19 | 101 | 50 | 50 | 超出范围 |
决策表:
三角形问题决策表 | |||||||||
---|---|---|---|---|---|---|---|---|---|
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
条件 | a+b>c | N | Y | Y | Y | Y | Y | Y | Y |
a+c>b | - | N | Y | Y | Y | Y | Y | Y | |
b+c>a | - | - | N | Y | Y | Y | Y | Y | |
a=b? | - | - | - | N | N | N | Y | Y | |
a=c? | - | - | - | N | N | Y | N | Y | |
b=c? | - | - | - | N | Y | - | - | - | |
动作 | 非三角形 | √ | √ | √ | |||||
一般三角形 | √ | ||||||||
等腰三角形 | √ | √ | √ | √ | |||||
等边三角形 | √ |
测试代码:
下面是我的程序接口,这个可以按自己的想法提前写好,(一开始难免会有一些小bug~)再用上面的测试用例进行测试,在测试中就会发现这些bug,比如在判断三角形类型时:等边三角形的判断要在等腰三角形之前…
ps:代码可以不用像我一样写复杂了(我只是很久没有用枚举了,练一练…),尽量写简单点,因为只是为了学习测试
#include <iostream>
#include <string>
#include <cmath>
const float ESP = 0.0001;
const float MIN = 1;
const float MAX = 100;
using namespace std;
struct Triangle
{
float a;
float b;
float c;
};
enum TriangleTypes
{
Equilateral,
Isosceles,
Right,
General
};
const string res[] =
{
"等边三角形",
"等腰三角形",
"直角三角形",
"一般三角形"
};
bool is_triangle(Triangle tr)
{
return (tr.a+tr.b>tr.c)&&(tr.a+tr.c>tr.b)
&&(tr.b+tr.c>tr.a);
}
bool is_right(float a,float b,float c)
{
/*由勾股定理
* 判断是否构成直角
* tip:不可将浮点变量用 “==” 或 “!=” 与任何数字比较
* 精度需要取绝对值比较
*/
float tmp = a*a + b*b - c*c;
return fabs(tmp) < ESP;
}
bool is_equal(float a,float b)
{
return fabs(a-b) < ESP;
}
int triangle_type(Triangle tr)
{
/* 判断三角形类型:等边,等腰,直角,一般
* Equilateral triangle
* Isosceles triangle
* Right triangle
* General triangle
*/
float a = tr.a;
float b = tr.b;
float c = tr.c;
if(is_equal(a,b) && is_equal(b,c) && is_equal(a,c))
{
return Equilateral; // "等边三角形";
}
if(is_equal(a,b) || is_equal(b,c) || is_equal(a,c))
{
return Isosceles; // "等腰三角形";
}
if(is_right(a,b,c) || is_right(a,c,b) || is_right(b,c,a))
{
return Right; // "直角三角形";
}
return General; // "一般三角形";
}
void print_triangle(Triangle tr)
{
cout<<"this triangle three lines are: ";
cout<<tr.a<<" "<<tr.b<<" "<<tr.c<<endl;
}
bool out_range(float a)
{
return (a<MIN) || (a>MAX);
}
int main()
{
Triangle tr;
while(cin>>tr.a>>tr.b>>tr.c)
{
print_triangle(tr);
cout<<"the test result: ";
if(out_range(tr.a)||out_range(tr.b)||out_range(tr.c))
{
cout<<"超出[1,100]范围"<<endl;
continue;
}
if(is_triangle(tr))
{
cout<<res[triangle_type(tr)]<<endl;
}
else
{
cout<<"非三角形"<<endl;
}
}
return 0;
}
总结
-
一般边界值分析:min,min+,max,max-,normal(4 * N+1,N为变量数,前四种4组用例,normal只需1组用例)
-
健壮边界值法:再一般的基础上加上:min-,max+(6 * N + 1)
-
等价类划分:有效等价类(符合规格说明且有意义),无效等价类(无意义,不合理);比如上述一般边界值分析用例全为有效等价类,而健壮性边界值分析补充的为无效等价类
-
决策表:由于等价类划分和边界值分析法只是孤立的考虑各个数据的测试效果,没有考虑输入数据的组合及其相互制约关系,而决策表考虑了多种条件的组合情况。
-
决策表根据条件项(输入)的取值产生符合规格的动作(输出),通常与条件的次序无关。