软件测试大作业

《软件质量保证与软件测试》大作业

基于蔡勒公式星期计算程序

测试报告

专业 班级 姓名 学号

1.问题的提出

1.1问题的来源

这次实验一开始打算测试PreDate或者计算器,老师在课上告诉我们什么是好程序,要编写好程序,要有好的编程习惯。回想一下我以前上机也是直接打#include就盲目地开始了。在电脑上翻开了以前C++课上编的一个根据日期计算星期的作业,编的实在太烂了。程序如下:

#include void main() {

inty,m,d,x,i,sum=0;

intaa[13]={0,0,31,60,91,121,152,182,213,244,274,305,335}; int bb[13]={0,0,31,59,90,120,151,181,212,243,273,304,334}; cout>y;

cout>m;

cout>d;

if(y12){cout

if((m==1||m==3||m==5||m==7||m==8||m==10||m==12)&&(d31))return; if( (m==4||m==6||m==9||m==11)&&(d30) )return;

if( (y%4==0&&y%100!=0||y%400==0)&&m==2&&(d29) )return; if( (m==2)&&!(y%4==0&&y%100!=0||y%400==0)&&(d28) )return; for(i=1;i

{

if(i%4==0&&i%100!=0||i%400==0) sum+=366; else sum+=365; }

if(y%4==0&&y%100!=0||y%400==0) {sum+=aa[m];sum+=d;}//计算一年到本日的总天数

else {sum+=bb[m];sum+=d;} x=sum%7; if(x!=0)

cout

别的问题先不说,光是那两个数组就很糟糕,如果让别人读根本就不能读明白,自己也是费了较大力气才读懂,运行以后发现了好多Bug,根本就不是一个可使用的程序。于是就决定把这个程序重新尽自己的所学,做一个比较好的版本。就有了这个测试作业的选题。

1.2星期计算公式——蔡勒公式

蔡勒(Zeller)公式,是一个计算星期的公式,给一个日期,就能用这个公式推算出是星期几。但是由于罗马教皇格里高利十三世在1582年组织了一批天文学家,根据哥白尼日心说计算出来的数据,对儒略历作了修改。将1582年10月5日到14日之间的10天宣布撤销,继10月4日之后为10月15日。因此,蔡勒公式只适合于1582年10月15日之后的情形。

w = [c/4] – 2c + y + [y/4] + [13 * (m+1) / 5] + d - 1

OR:w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1

若要计算的日期是在1582年10月4日或之前,公式则为

w=y+[y/4]+[c/4]-2c+[13(m+1)/5]+d+3

符号意义

w:星期; w对7取模得:0-星期日,1-星期一,2-星期二,3-星期三,4-星期四,5-星期五,6-星期六 c:世纪-1(前两位数) y:年(后两位数)

m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,比如2003年1月1日要看作2002年的13月1日来计算) d:日

[ ]代表取整,即只要整数部分。

后来人们将这一新的历法称为“格里高利历”,简称格里历或公历。

1.3软件的功能概述

根据日期计算星期就是用户想知道某一个日期所对应的是星期几,比如用户想知道自己的生日那天是星期几,好安排自己的生日Party。该软件可以实现用户的需求。如果用户输入一个日期,把输入的日期所对应的星期快速输出出来。

2.星期计算程序的细节

2.1星期计算程序的整体描述及函数之间的关系

软件在一个C++控制台工程文件里面,如图2-1所示。

图2-1 Visual studio 2010中SoftWareTest工程

星期计算程序的总体结构分析

软件是由包含

main

函数在内的三个函数实现的其中

boolcheckDay(intyear,intmonth,int day)专门用于检测所输入的数字日期字符是不是符合逻辑;

intdayToWeek(intyear,intmonth,int day)专门用于计算所输入日期所对应的星期; int main()函数,是程序的主函数,它用来接收并初步检测用户的输入,然后调用checkDay(intyear,intmonth,int day)函数以确保输入的日期是合法的日期,随后调用intdayToWeek(intyear,intmonth,int day)

函数实现计算,同时由于星期日所对应

的返回值是0,故要对其进行单独处理。

图2-2 程序流程图

2.2 星期计算程序的C++实现

#include using namespace std;

boolcheckDay(intyear,intmonth,int day)//此函数用于检测所输入的年月日是不 {//是一个合乎逻辑的年月日; if(year12) return false;

int m[]= {31,0,31,30,31,30,31,31,30,31,30,31}; //定义一个月份所对应的天数的数组,2 if(year%4==0&&year%100!=0||year%400==0) //月是变化的所以暂时设为0; m[1]=29; //是闰年,2月29天; else m[1]=28; //是平年; return(day>=1)&&(day

intdayToWeek(intyear,intmonth,int day)//该函数采用蔡勒公式计算日期所对应的 {//星期; inty,c,w,m,d,week; int sum=year*10000+month*100+day;//为了分开1584年10月4日之前和之后, if (month15821004) w=y+int(y/4)+int(c/4)-2*c+int(26*(m+1)/10)+d-1;//蔡勒公式1582年10月

//4日之后的计算公式;

else w=y+int(y/4)+int(c/4)-2*c+int(13*(m+1)/5)+d+3; //蔡勒公式1582年10月

//4日之前的计算公式;

week=(w%7+7)%7; return week; }

int main()

{ intyear,month,day,week;

do{ cout

//件执行一次,以避免不满足初始检测条件

cin>>year;

while(!cin || isalpha(getchar())) //循环避免输入的不是数字字符 { cin.clear(); cin.ignore(1024,'\n'); cout>year; }

cout>month;

while(!cin || isalpha(getchar())) { cin.clear(); cin.ignore(1024,'\n'); cout>month; }

cout>day;

while(!cin || isalpha(getchar())) { cin.clear(); cin.ignore(1024,'\n'); cout>day; }

}while (!checkDay(year,month,day)); //在所输入的都是数字字符之后检测

//日期的逻辑,使得日期是合法的;

week=dayToWeek(year,month,day); //利用得到的合法

//日期调用星期计算函数;

cout

//函数返回值是int,所以星期日在此时才处理;

else cout

3.星期计算程序的测试思路

3.1功能性测试

程序的规格说明很明确,功能也很单一,对其进行功能性测试,以希望能尽可能对程序的运行结果进行全面合理的判断。

3.1.1边界值测试

使用边界值测试里的最坏情况测试,由于程序输入变量是三个,所以可使用三重循环解决边界值测试,开发出测试程序。由于网络上万年历比较权威的产品

日期是从1901-2050,所以我进行边界值测试,年的边界的选取就按1901-2050来进行。虽然程序可以计算任意合法日期的星期,但是为了验证测试结果,所以只能做这样的选择。图3-1是进行测试结果验证的万年历。

图3-1 用于验证测试结果的万年历

3.1.2弱健壮等价类测试

由于年月日这三个变量之间存在很强的依赖性,使用边界值测试难免会存在冗余和漏洞,所以继续进行等价类测试,希望能尽可能进行完备的测试,同时也能避免冗余。

测试考虑无效等价类得到如下的等价类: M1={月份:1≤月份≤12} D1={日期:1≤日期≤31} Y1={年:0≤年}

3.1.3基于决策表测试

月日年三者之间存在着很强的逻辑依赖关系,所以可以选取基于决策表的测试避免大量的冗余,同时也能较全面的覆盖

M1={月份:每月有30天} M2={月份:每月有31天} M3={月份:此月是2月} D1={日期:1≤日期≤28} D2={日期:日期=29} D3={日期:日期=30} D4={日期:日期=31} Y1={年:年是闰年} Y2={年:年是平年}

C1:月在 C2:日在 C3:年在

1 M1 D1 — X

2 M1 D2 — X

3 M1 D3 — X

4 M1 D4 — X

5 M2 — — X

6 M3 D1 — X

7 M3 D2 Y1 X

8 M3 D2 Y2 X

9 M3 D3 — X

10 M3 D4 — X

行为

输入无效 输入有效

3.2结构性测试

前面分析了系统使用三种功能性测试,由于功能性测试存在潜在的大量的冗余和漏洞,所以在此继续进行结构性测试,以期达到较完备的测试。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44

#include using namespace std;

boolcheckDay(intyear,intmonth,int day)//此函数用于检测所输入的年月日是不 {//是一个合乎逻辑的年月日; if(year12) return false; int m[]= {31,0,31,30,31,30,31,31,30,31,30,31}; //定义一个月份所对应的天数的数组,2 if(year%4==0&&year%100!=0||year%400==0) //月是变化的所以暂时设为0; m[1]=29; //是闰年,2月29天; else m[1]=28; //是平年; return(day>=1)&&(day

intdayToWeek(intyear,intmonth,int day)//该函数采用蔡勒公式计算日期所对应的 {//星期; inty,c,w,m,d,week; int sum=year*10000+month*100+day;//为了分开1584年10月4日之前和之后, if (month15821004) w=y+int(y/4)+int(c/4)-2*c+int(26*(m+1)/10)+d-1;//蔡勒公式1582年10月

//4日之后的计算公式;

else w=y+int(y/4)+int(c/4)-2*c+int(13*(m+1)/5)+d+3; //蔡勒公式1582年10月

//4日之前的计算公式;

week=(w%7+7)%7; return week; }

int main()

{ intyear,month,day,week;

do{ cout

//件执行一次,以避免不满足初始检测条件

cin>>year;

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79

while(!cin || isalpha(getchar())) //循环避免输入的不是数字字符 { cin.clear(); cin.ignore(1024,'\n'); cout>year; }

cout>month;

while(!cin || isalpha(getchar())) { cin.clear(); cin.ignore(1024,'\n'); cout>month; }

cout>day;

while(!cin || isalpha(getchar())) { cin.clear(); cin.ignore(1024,'\n'); cout>day; }

}while (!checkDay(year,month,day)); //在所输入的都是数字字符之后检测

//日期的逻辑,使得日期是合法的;

week=dayToWeek(year,month,day); //利用得到的合法

//日期调用星期计算函数;

cout

//函数返回值是int,所以星期日在此时才处理;

else cout

根据程序图可以得到DD路径图如下所示:

图3-2 DD-路径图

上面所示的DD-路径图包含了太多的循环,找出所有路径来非常困难,前面一些循环主要是为了测试输入的年月日是数字字符,使用的检测方式也是C++标准库函数,所以在这里去掉字符检测,年大于0判断,简化上面的DD-

路径,得到的简化模型如下所示:

图3-3 简化后的DD-路径图

根据路径覆盖准则可以生成测试用例,同时要避免冗余。

结构性测试覆盖指标达到C1,即所有DD路径,根据这个指标可以开发相应的测试用例。

DD-路径有:(1)开始->1->2->3->4->5->结束 (2)开始->1->2->3->4->6->结束 (3)开始->1->2->1->3->4->5->结束 (4)开始->1->2->1->3->4->6->结束 (5)开始->1->2->3->1->2->3->4->5->结束 (6)开始->1->2->3->1->2->3->4->6->结束 (7)开始->1->2->3->1->2->1->2->3->4->5->结束 (8)开始->1->2->3->1->2->1->2->3->4->6->结束

3.3本章小结

本章针对被测程序分析系统要采取边界值测试中的最坏情况测试,弱健壮等价类测试,基于决策表的测试,当然这些都是功能性测试。同时也根据DD路径图分析了结构性测试用例的开发。下一章将根据本章的内容生成测试用例。

4.测试用例

(1)根据上一章测试思路里面的分析,我们要采用最坏情况测试,下表就是最坏情况测试的测试用例

测试用例

1 2 3 4 5 6 7 8 9

月份 1 1 1 1 1 2 2 2 2

日期 1 2 15 30 31 1 2 15 30

年份 1901 1901 1901 1901 1901 1901 1901 1901 1901

预期输出

2 3 2 3 4 5 6 5

日期不存在

实际输出是否正确

Y Y Y Y Y Y Y Y Y

11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

6 6 6 6 6 11 11 11 11 11 12 12 12 12 12 1 1 1 1 1 2 2 2 2 2 6 6 6 6 6 11 11 11 11 11 12 12 12 12 12 1 1 1

1 2 15 30 31 1 2 15 30 31 1 2 15 30 31 1 2 15 30 31 1 2 15 30 31 1 2 15 30 31 1 2 15 30 31 1 2 15 30 31 1 2 15

1901 1901 1901 1901 1901 1901 1901 1901 1901 1901 1901 1901 1901 1901 1901 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 2000 2000 2000

6 0 6 0

日期不存在

5 6 5 6

日期不存在

0 1 0 1 2 3 4 3 4 5 6 0 6

日期不存在 日期不存在 0 1 0 1

日期不存在

6 0 6 0

日期不存在

1 2 1 2 3 6 0 6

Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97

1 2 2 2 2 2 6 6 6 6 6 11 11 11 11 11 12 12 12 12 12 1 1 1 1 1 2 2 2 2 2 6 6 6 6 6 11 11 11 11 11 12 12

31 1 2 15 30 31 1 2 15 30 31 1 2 15 30 31 1 2 15 30 31 1 2 15 30 31 1 2 15 30 31 1 2 15 30 31 1 2 15 30 31 1 2

2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2049 2049 2049 2049 2049 2049 2049 2049 2049 2049 2049 2049 2049 2049 2049 2049 2049 2049 2049 2049 2049 2049

1 2 3 2

日期不存在 日期不存在

4 5 4 5

日期不存在

3 4 3 4

日期不存在

5 6 5 6 0 5 6 5 6 0 1 2 1

日期不存在 日期不存在

2 3 2 3

日期不存在

1 2 1 2

日期不存在

3 4

Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

12 12 1 1 1 1 1 2 2 2 2 2 6 6 6 6 6 11 11 11 11 11 12 12 12 12 12

30 31 1 2 15 30 31 1 2 15 30 31 1 2 15 30 31 1 2 15 30 31 1 2 15 30 31

2049 2049 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050 2050

4 5 6 0 6 0 1 2 3 2

日期不存在 日期不存在

3 4 3 4

日期不存在

2 3 2 3

日期不存在

4 5 4 5 6

Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y

(2)根据弱健壮等价类的划分,以及弱健壮等价类基本原理,弱健壮等价类测试一共产生6个测试用例,因此所得到的测试用例如下表所示:

测试用例 WR1 WR2 WR3 WR4 WR5 WR6

月份 6 -1 13 6 6 6

日期 15 15 15 -1 32 15

年份 2011 2011 2011 2011 2011 -1

预期输出 2 月份无效 月份无效 日期无效 日期无效 年无效

实际输出是否正确 Y Y Y Y Y Y

(3)基于上一章决策表的测试的分析,得出下表测试用例

用例ID 1

月份 4

日期 15

年份 2011

预期输出

2

实际输出是否正确

Y

3 4 5 6 7 8 9 10

4 4 1 2 2 2 2 2

30 31 15 28 29 29 30 31

2011 2011 2011 2011 1996 2011 2011 2011

6 日期无效

6 1 4 日期无效 日期无效 日期无效

Y Y Y Y Y Y Y Y

5.测试过程描述

边界值自动测试代码:

图5-1 自动化测试代码

这里面输出的星期0是代表星期日的,主要是为了测试,没做0对应的星期日处理。

弱健壮等价类测试,仅六个测试用例。所以将六个测试用例分别输入程序运行可以得出运行结果。同样,基于决策表的测试和DD路经测试也如此。

6.测试结果分析

这个是自动化运行测试的结果截图

图6-1 自动化运行后测试结果

根据测试用例手动输入的运行结果:

图6-2 部分运行结果

使用边界值测试中的最坏情况测试,测试用例数量庞大,但是也最容易自动化生成,弱健壮等价类测试考虑了无效值,能弥补最坏情况测试的不足。由于年月日直接存在着很强的逻辑关系,所以边界值测试存在的大量的冗余还有一些潜在的漏洞,对于这种情况使用决策表测试能保证一种完备的测试。这三者结合起来,能从不同的角度比较全面的测试。以上这些都是功能性测试,受到功能性测试的约束,所以进行结构性测试中的DD路经测试。进行完这些测试。基本上达到了测试的目标。

到目前为止,程序没发现什么问题,但是像上图所示的12年2月29日是不是是星期日暂时无法查证。其实系统也不必考虑这些,因为基本上人们不会想知道12年2月29日是星期几,这个是系统的一个遗留问题。

七.总结

到此,这学期也马上结束了。研究生第一年的学习生活也将画上一个句号。 通过这次大作业程序的开发和测试报告的编写,让我能把所学的知识有一个整体的实践应用。也发现了自己存在一些问题。在今后的学习中能通过不断的学习提升自己的能力。

(一)欲知大道,必先知史

一学期软件测试课程的学习,和近一年陈老师的教导,让我学到了很多。老师讲述的那些实践经历让我懂得了许多。我知道了软件测试乃至软件工程的发展历史。老师在分享软件测试的艺术的同时,也分享做人的道理。 (二)谁人人前无人测,谁人背后不测人。

正如老师所说的,测试其实无处不在,无时不在。马上就要出去实习了,这也是对自己研一一年以及以前所学的一次测试,希望自己能经受的住测试。在丰富自己知识的同时也能为研究生的顺利毕业打好基础。

最后谢谢陈老师!很荣幸能成为您的学生!

21


© 2024 实用范文网 | 联系我们: webmaster# 6400.net.cn