实 验 报 告
一、实验目的
1.掌握如何运用边界值、等价类和决策表等黒盒测试方法进行测试用例设计。
2.初步熟悉轻量级自动化测试中测试驱动的编写与执行。
二、实验内容
1、题目
前一日函数PreDate是NextDate的逆函数(代码实现见下),实现功能为:函数接受一个MyDate类型的输入变量后通过计算返回该输入日期的前一日期值(如输入1999-3-6,则返回1999-3-5)。有效处理范围为1800 年到2050 年之间的某个日期,当输入无效时返回日期值为:年为0,月、日与输入值相同(例如输入1990-2-31,则返回0-2-31)。
请分别用边界值方法、等价类划分方法、决策表方法对前一日函数进行测试用例设计,并根据设计的用例集执行测试,对测试结果进行总结分析。
被测代码:(Leapyear函数比较简单,此处不做测试,直接作为PreDate的下级调用函数。以下代码粘贴到VC环境后与测试驱动程序结合即可执行测试。)
#include"stdio.h"
typedef struct MyDate{
int month;
int day;
int year;
}MyDate;
MyDate PreDate(MyDate date);
int Leapyear(int year);
MyDate PreDate(MyDate date)
{
MyDate yesterday;
yesterday.month = date.month; // initialization
yesterday.day = date.day;
yesterday.year = date.year;
//-------------验证输入日期的有效性-------------
int v=1; //v==0表示无效,v==1表示有效
if(date.year<1800 || date.month<0 || date.day<0 || date.day>31 || date.month>12 || date.year>2050)
v=0;
//---------------计算输入日期的前一日期-------------
if(v==1)
{
if(date.day>1)
yesterday.day=date.day-1;
else
{
switch(date.month)
{
case 1:
case 2:
case 4:
case 6:
case 8:
case 9:
case 11:
{
yesterday.month=date.month-1;
yesterday.day=31;
break;
}
case 3:
{
if(Leapyear(date.year))
{
yesterday.month=2;
yesterday.day=29;
}
else
{
yesterday.month=2;
yesterday.day=28;
}
break;
}
case 5:
case 7:
case 10:
case 12:
{
yesterday.month=date.month-1;
yesterday.day=30;
break;
}
}
}
}
else yesterday.year=0;
return yesterday;
}
int Leapyear(int year)
{
if((year%4==0&&year%100!=0) || (year%400==0))
return 1;
else return 0;
}
2、测试用例设计
1)边界值
A 边界值分析:
C1 1<=month<=12
C2 1<=day<=31
C3 1800<=year<=2050
B 边界值测试用例
2等价类
A 等价类划分
M1={月份:每月30天}
M2={月份:每月31天(除三月外)}
M3={月份:此月是1月}
M4={月份:此月是2月}
M5={月份:此月是3月}
M6={月份:此月是8月}
D0={日期:day=1}
D1={日期:2<=day<=28}
D2={日期:day=29}
D3={日期:day=30}
D4={日期:day=31}
Y1={年:year=闰年}
Y2={年:year=平年}
B 等价类测试用例
ID
1 1996 1 1 1995 12 31
2 20## 1 1 20## 12 31
3 1996 1 16 1996 1 15
4 20## 1 16 20## 1 15
5 1996 1 29 1996 1 28
6 20## 1 29 20## 1 28
7 1996 1 30 1996 1 29
8 20## 1 30 20## 1 29
9 1996 1 31 1996 1 30
10 20## 1 31 20## 1 30
11 1996 2 1 1996 1 31
12 20## 2 1 20## 1 31
13 1996 2 16 1996 2 15
14 20## 2 16 20## 2 15
15 1996 2 29 1996 2 28
16 20## 2 29 0 2 28
17 1996 2 30 0 2 29
18 20## 2 30 0 2 29
19 1996 2 31 0 2 30
20 20## 2 31 0 2 30
21 1996 3 1 1996 2 29
22 20## 3 1 20## 2 28
23 1996 3 16 1996 3 15
24 20## 3 16 20## 3 15
25 1996 3 29 1996 3 28
26 20## 3 29 20## 3 28
27 1996 3 30 1996 3 29
28 20## 3 30 20## 3 29
29 1996 3 31 1996 3 30
30 20## 3 31 20## 3 30
31 1996 6 1 1996 5 31
32 20## 6 1 20## 5 31
33 1996 6 16 1996 6 15
34 20## 6 16 20## 6 15
35 1996 6 29 1996 6 28
36 20## 6 29 20## 6 28
37 1996 6 30 1996 6 29
38 20## 6 30 20## 6 29
39 1996 6 31 0 6 30
40 20## 6 31 0 6 30
41 1996 7 1 1996 6 30
42 20## 7 1 20## 6 30
43 1996 7 16 1996 7 15
44 20## 7 16 20## 7 15
45 1996 7 29 1996 7 28
46 20## 7 29 20## 7 28
47 1996 7 30 1996 7 29
48 20## 7 30 20## 7 29
49 1996 7 31 1996 7 30
50 20## 7 31 20## 7 30
51 1996 8 1 1996 7 31
52 20## 8 1 20## 7 31
53 1996 8 16 1996 8 15
54 20## 8 16 20## 8 15
55 1996 8 29 1996 8 28
56 20## 8 29 20## 8 28
57 1996 8 30 1996 8 29
58 20## 8 30 20## 8 29
59 1996 8 31 1996 8 30
60 20## 8 31 20## 8 30
3)决策表
简化后的决策表
3、执行测试
1)测试驱动程序代码:
void DriverpredateRevenueAccount()
{ //--------1. 设置局部变量-----------
int tcPassNum = 0;
int tcFailNum = 0; // 存储通过和失败的测试用例总数
FILE* pFpFrom = NULL; // 数据文件的指针,存储测试用例的基本信息
FILE* pFpTo = NULL; // 记录测试用例执行结果的文件的指针
//--------2. 打开数据文件,准备读取测试用例的数据-----------
char* DataFileName = "mydate.txt";
pFpFrom = fopen( DataFileName, "r" );
if( !pFpFrom )
{
printf( "读取数据失败,返回\n" );
return;
}
// 打开数据文件,准备记录测试用例执行结果
char* DataFileTestResultName = "predate.txt";
pFpTo = fopen( DataFileTestResultName, "w+t" );
if( !pFpTo )
{
printf( "打开文件失败,返回\n" );
return;
}
fprintf( pFpTo, "----------对函数predateRevenueAccount的单元测试结果-------------\n" );
//-----------3. 执行测试用例,记录测试结果-----------
int TCID = 0;
MyDate originalAmount; // 测试用例的输入
MyDate expectedOutcome; // 测试用例的预期输出
MyDate actualOutcome; // 测试用例的实际输出
printf( "对函数predateRevenueAccount展开单元测试\n" );
while( !feof(pFpFrom) ){// 不断读取每个测试用例的数据
fscanf( pFpFrom, "%d ", &TCID ); // 读入测试用例的ID
fscanf( pFpFrom, "%d ", &originalAmount.year );
fscanf( pFpFrom, "%d ", &originalAmount.month );// 读入测试用例的输入
fscanf( pFpFrom, "%d ", &originalAmount.day );
fscanf( pFpFrom, "%d ", &expectedOutcome.year );// 读入测试用例的预期输出
fscanf( pFpFrom, "%d ", &expectedOutcome.month );
fscanf( pFpFrom, "%d ", &expectedOutcome.day );
actualOutcome = PreDate( originalAmount );// 执行测试用例
// 输出测试用例的信息
printf( "测试用例%d: 输入%d年%d月%d日, 预期输出%d年%d月%d日,实际输出%d年%d月%d日, ", TCID, originalAmount.year,originalAmount.month ,originalAmount.day,
expectedOutcome.year,expectedOutcome.month ,expectedOutcome.day, actualOutcome.year, actualOutcome.month,actualOutcome.day);
if( actualOutcome.year==expectedOutcome.year&&actualOutcome.month==expectedOutcome.month&&actualOutcome.day==expectedOutcome.day)
{// 若测试用例通过,则记录通过的用例总数
tcPassNum ++;
printf( "通过\n" );
fprintf( pFpTo, "测试用例%d: Pass\n", TCID ); // 将测试用例的执行结果存入结果文件
}
else
{
tcFailNum ++;
printf( "失败\n" );
fprintf( pFpTo, "测试用例%d: Fail\n", TCID ); // 将测试用例的执行结果存入结果文件
}
}
fclose( pFpFrom );// 关闭测试用例数据文件
//-----------4. 统计测试结果-----------
printf( "共执行%d 个测试用例,其中%d 个通过,%d 个失败\n", tcPassNum+tcFailNum, tcPassNum, tcFailNum );
fprintf( pFpTo, "共执行%d 个测试用例,其中%d 个通过,%d 个失败\n", tcPassNum+tcFailNum, tcPassNum, tcFailNum );
fclose( pFpTo );// 关闭结果记录文件
}
void main()
{
DriverpredateRevenueAccount();
}
2)测试执行结果与分析
1边界值测试
分析:
共执行19 个测试用例,其中18 个通过,1 个失败
2等价类测试
分析:
共执行19 个测试用例,其中18 个通过,1 个失败。
决策表:
分析:
共执行17 个测试用例,其中13 个通过,4 个失败
三、实验小结