实验测试单元
Posted xy1229
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实验测试单元相关的知识,希望对你有一定的参考价值。
一、实验目的
1)掌握单元测试的方法
2) 学习XUnit测试原理及框架;
3)掌握使用测试框架进行单元测试的方法和过程。
二、实验内容与要求
1)源码
#include "stdio.h" #include "string.h" #include "windows.h" #include "time.h" #define N 49//1表示棋子,只有黑色棋子 int chess[N+2][N+2];//定义棋盘大小 int chess0[N+2][N+2];//辅助棋盘 void Initialize();//初始化一个对局函数 void RunGame();//进行游戏 int count_cellsNumber(int i,int j);//计算生命周围的生命数量 void Data();//调用已存的游戏数据 void main() { system("mode con cols=99 lines=50");//设置窗口大小 system("color 70");//设置颜色 Initialize();//初始化一个对局函数 RunGame();//进行游戏 } void Initialize()//初始化一个对局函数 { Data();//调用已存的游戏数据 } void Data()//调用已存的游戏数据 { int i,j; srand((unsigned)time(NULL)); for(i=0;i<N;i++){ for(j=0;j<N;j++) chess[i][j]=rand()%2; } /* int p=12; int l; for(l=-16;l<=16;l++) //if(l!=-8&&l!=0&&l!=4) chess[N/2+1][N/2+1+l]=1; */ /* //滑翔机 chess[1][3]=1;chess[2][1]=1;chess[2][3]=1;chess[3][2]=1;chess[3][3]=1; */ /* //高斯帕滑翔机 chess[1][p+11]=1;chess[1][p+13]=1; chess[2][p+10]=1;chess[2][p+13]=1; chess[3][p+9]=1;chess[3][p+10]=1;chess[3][p+21]=1;chess[3][p+28]=1; chess[4][p+1]=1;chess[4][p+2]=1;chess[4][p+7]=1;chess[4][p+8]=1;chess[4][p+12]=1;chess[4][p+21]=1;chess[4][p+27]=1;chess[4][p+29]=1; chess[5][p+1]=1;chess[5][p+2]=1;chess[5][p+9]=1;chess[5][p+10]=1;chess[5][p+20]=1;chess[5][p+27]=1;chess[5][p+28]=1;chess[5][p+30]=1; chess[6][p+10]=1;chess[6][p+13]=1;chess[6][p+16]=1;chess[6][p+17]=1;chess[6][p+27]=1;chess[6][p+28]=1;chess[6][p+30]=1;chess[6][p+31]=1;chess[6][p+35]=1;chess[6][p+36]=1; chess[7][p+11]=1;chess[7][p+13]=1;chess[7][p+16]=1;chess[7][p+19]=1;chess[7][p+20]=1;chess[7][p+21]=1;chess[7][p+22]=1;chess[7][p+27]=1;chess[7][p+28]=1;chess[7][p+30]=1;chess[7][p+35]=1;chess[7][p+36]=1; chess[8][p+16]=1;chess[8][p+17]=1;chess[8][p+18]=1;chess[8][p+19]=1;chess[8][p+27]=1;chess[8][p+29]=1; chess[9][p+17]=1;chess[9][p+18]=1;chess[9][p+28]=1; */ } void cells_state(int i,int j) { int living_cellsnumber=0; living_cellsnumber=count_cellsNumber(i,j); if(chess[i][j]==1){ if(living_cellsnumber<2) chess0[i][j]=0;//如果一个生命周围的生命少于2个,它在回合结束后死亡。 else if(living_cellsnumber>3) chess0[i][j]=0;//如果一个生命周围的生命超过3个,它在回合结束后死亡。 else if(living_cellsnumber==2||living_cellsnumber==3) chess0[i][j]=1;//如果一个生命周围有2或3个生命,它在回合结束时保持原样。 } else if(chess[i][j]==0){ if(living_cellsnumber==3) chess0[i][j]=1;//如果一个死格周围有3个生命,它在回合结束时获得生命。 } } void RunGame()//进行游戏 { int i,j,s=0; int flag=0; while(1) { system("cls");//清理屏幕,准备写入 for(i=1;i<N+1;i++) { for(j=1;j<N+1;j++) if(chess[i][j]==1) printf("█");//printf("■"); else if(chess[i][j]==0) printf(" "); printf(" "); } for(i=1;i<N+1;i++) for(j=1;j<N+1;j++) { cells_state(i,j); } for(i=1;i<N+1;i++) for(j=1;j<N+1;j++) chess[i][j]=chess0[i][j]; Sleep(10); if(flag==0) { getchar(); flag=1; } } } int count_cellsNumber(int xline,int yline)//计算生命周围的生命数量 { int living_cellsnumber=0,i,j; for(i=-1;i<=1;i++){ for(j=-1;j<=1;j++){ if(!(i==0&&j==0)&&chess[xline+i][yline+j]==1) living_cellsnumber++; } }return living_cellsnumber; }
2)测试用例设计 (结合单元测试的内容和模块功能设计测试用例)
测试用例流程:需求文档分析>功能模块划分>测试用例编写>测试用例整理与维护
1.生命游戏需求分析:
-
每个细胞的状态由该细胞及周围 8 个细胞上一次的状态所决定;
-
如果一个细胞周围有 3 个细胞为生,则该细胞为生,即该细胞若原先为死则转为生,若原先为生则保持不变;
-
如果一个细胞周围有 2 个细胞为生,则该细胞的生死状态保持不变;
-
在其它情况下,该细胞为死,即该细胞若原先为生则转为死,若原先为死则保持不变。
2.生命游戏的功能划分:
Initialize()初始化功能,RunGame()进行游戏功能,count_cellsNumber()计算生命数量功能,Data()调用游戏数据功能
3.测试用例编写:
用例编号 | 1 | 2 | 3 |
测试数据 | 无细胞 | 全部都是细胞 | 一半是细胞,一半不是细胞 |
测试步骤 |
运行.c文件,出现细胞初始化情况,回车开始生命游戏,设置成无细胞情况:
|
运行.c文件,出现细胞初始化情况,会传染开始生命游戏,设置成全都是细胞的情况:
|
运行.c文件,出现细胞初始化情况,会传染开始生命游戏,设置成一半细胞的情况:
|
预期结果 | 运行后无细胞产生 |
|
|
实际结果 |
|
无 | 无
|
备注 | 源文件是按细胞随机生成编写的,极少数会出现0细胞情况,所以会有细胞产生 | 源文件无法设置,预期结果采用网页上的生命游戏给出 | 源文件无法设置,预期结果采用网页上生命游戏给出 |
3)选择的测试框架介绍、安装过程
一.PC-lint v9介绍:
PC-lint/FlexeLint发现C和C+ +程序中的怪癖、异质、失灵和臭虫。这样分析的目的是发现这些程序中的在集成前的潜在的问题,揭示可能包含敏感的、未检测到的错误的不寻常的结构。因为它寻找几个模块而不仅仅是一个,可以发现编译器不能发现的事情。它通常比编译关于很多细节更爱挑剔。
PC-Lint是C/C++软件代码静态分析工具,你可以把它看作是一种更加严格的编译器。它不仅可以检查出一般的语法错误,还可以检查出那些虽然符合语法要求但不易发现的潜在错误。
PC-lint 中文手册:https://max.book118.com/html/2018/0202/151550624.shtm
二、安装过程:
1.安装PC-lint v9.0:
2.PC-lint v9配置过程:
3.VC++6.0配置过程:
PC-Lint与VC集成的方式就是在VC的集成开发环境中添加几个定制的命令,添加定制命令的方法是选择“工具”的“定制”命令,在弹出的定制窗口中选择“工具”标签,在定制工具命令的标签页中添加定制命令。
接下来主要是配置用PC-Lint检查当前的文件是否存在隐藏错误等,注意,命令里的路径是你的安装路径,后续的变量也是如此的,这一点切记,路径不同的话仅需将路径替换。似于配置环境变量,命令:D:softwarePC+lintlintlint-nt.exe;变量:-i"D:softwarePC+lintlint" -u std.lnt env-vc6.lnt "$(FileName)$(FileExt)";std.lnt是为VC编译环境定制的配置文件,$(FileName)和$(FileExt)是VC集成开发环境的环境变量,"$(FileName)$(FileExt)"表示当前文件的文件名。同时选中使用输出窗口选项。
如果要检查当前的整个项目的内容,这一步是必须的,首先需要将这个项目的错误导入到某个文件后,然后通过后一条命令即PCLint Current Project命令将文件中的内容输出。配置PCLint Export Project命令如下:命令:D:softwarePC+lintlintlint-nt.exe;变量:+linebuf$(TargetName).dsp>$(TargetName).lnt;参数+linebuf表示加倍行缓冲的大小,最初是600 bytes,行缓冲用于存放当前行和你读到的最长行的信息。$(TargetName)是VC集成开发环境的环境变量,表示当前激活的Project名字同时选中Use Output Window选项。
配置PCLint Cuurent Project命令如下:命令:D:softwarePC+lintlintlint-nt.exe;变量:+ffn -i"D:softwarePC+lintlint" std.lnt env-vc6.lnt $(TargetName).lnt;这个命令的结果就是将整个工程的检查结果输出到与工程同名的.chk文件中。参数中+ffn表示Full File Names,可被用于控制是否使用的完整路径名称表示。同时选中Use Output Window选项
配置完此项后,便在VC++ 6.0的Tools下出现上述配置的命令,此时PC-Lint关于VC++6.0的安装配置完成,读者可以利用这些命令对整个项目的进行安全性和错误性检查。
4 )测试代码
#include "stdio.h" #include "string.h" #include "windows.h" #include "time.h" #define N 49//1表示棋子,只有黑色棋子 int chess[N+2][N+2];//定义棋盘大小 int chess0[N+2][N+2];//辅助棋盘 void Initialize();//初始化一个对局函数 void RunGame();//进行游戏 int count_cellsNumber(int i,int j);//计算生命周围的生命数量 void Data();//调用已存的游戏数据 void main() { system("mode con cols=99 lines=50");//设置窗口大小 system("color 70");//设置颜色 Initialize();//初始化一个对局函数 RunGame();//进行游戏 } void Initialize()//初始化一个对局函数 { Data();//调用已存的游戏数据 } void Data()//调用已存的游戏数据 { int i,j; srand((unsigned)time(NULL)); for(i=0;i<N;i++){ for(j=0;j<N;j++) chess[i][j]=rand()%2; } /* int p=12; int l; for(l=-16;l<=16;l++) //if(l!=-8&&l!=0&&l!=4) chess[N/2+1][N/2+1+l]=1; */ /* //滑翔机 chess[1][3]=1;chess[2][1]=1;chess[2][3]=1;chess[3][2]=1;chess[3][3]=1; */ /* //高斯帕滑翔机 chess[1][p+11]=1;chess[1][p+13]=1; chess[2][p+10]=1;chess[2][p+13]=1; chess[3][p+9]=1;chess[3][p+10]=1;chess[3][p+21]=1;chess[3][p+28]=1; chess[4][p+1]=1;chess[4][p+2]=1;chess[4][p+7]=1;chess[4][p+8]=1;chess[4][p+12]=1;chess[4][p+21]=1;chess[4][p+27]=1;chess[4][p+29]=1; chess[5][p+1]=1;chess[5][p+2]=1;chess[5][p+9]=1;chess[5][p+10]=1;chess[5][p+20]=1;chess[5][p+27]=1;chess[5][p+28]=1;chess[5][p+30]=1; chess[6][p+10]=1;chess[6][p+13]=1;chess[6][p+16]=1;chess[6][p+17]=1;chess[6][p+27]=1;chess[6][p+28]=1;chess[6][p+30]=1;chess[6][p+31]=1;chess[6][p+35]=1;chess[6][p+36]=1; chess[7][p+11]=1;chess[7][p+13]=1;chess[7][p+16]=1;chess[7][p+19]=1;chess[7][p+20]=1;chess[7][p+21]=1;chess[7][p+22]=1;chess[7][p+27]=1;chess[7][p+28]=1;chess[7][p+30]=1;chess[7][p+35]=1;chess[7][p+36]=1; chess[8][p+16]=1;chess[8][p+17]=1;chess[8][p+18]=1;chess[8][p+19]=1;chess[8][p+27]=1;chess[8][p+29]=1; chess[9][p+17]=1;chess[9][p+18]=1;chess[9][p+28]=1; */ } void cells_state(int i,int j) { int living_cellsnumber=0; living_cellsnumber=count_cellsNumber(i,j); if(chess[i][j]==1){ if(living_cellsnumber<2) chess0[i][j]=0;//如果一个生命周围的生命少于2个,它在回合结束后死亡。 else if(living_cellsnumber>3) chess0[i][j]=0;//如果一个生命周围的生命超过3个,它在回合结束后死亡。 else if(living_cellsnumber==2||living_cellsnumber==3) chess0[i][j]=1;//如果一个生命周围有2或3个生命,它在回合结束时保持原样。 } else if(chess[i][j]==0){ if(living_cellsnumber==3) chess0[i][j]=1;//如果一个死格周围有3个生命,它在回合结束时获得生命。 } } void RunGame()//进行游戏 { int i,j,s=0; int flag=0; while(1) { system("cls");//清理屏幕,准备写入 for(i=1;i<N+1;i++) { for(j=1;j<N+1;j++) if(chess[i][j]==1) printf("█");//printf("■"); else if(chess[i][j]==0) printf(" "); printf(" "); } for(i=1;i<N+1;i++) for(j=1;j<N+1;j++) { cells_state(i,j); } for(i=1;i<N+1;i++) for(j=1;j<N+1;j++) chess[i][j]=chess0[i][j]; Sleep(10); if(flag==0) { getchar(); flag=1; } } } int count_cellsNumber(int xline,int yline)//计算生命周围的生命数量 { int living_cellsnumber=0,i,j; for(i=-1;i<=1;i++){ for(j=-1;j<=1;j++){ if(!(i==0&&j==0)&&chess[xline+i][yline+j]==1) living_cellsnumber++; } }return living_cellsnumber; }
5)测试结果与分析
测试结果:
分析:
a)include <stdio.h>表示搜索stdio.h这个文件的路径在option中指定的位置,include "stdio.h"表示搜索stdio.h这个文件的路径在当前工作文件所在的位置,即""与<>表示搜索的路径不同。
b).lnt(1)安装路径必须是绝对路径,或者把PC-Lint的安装路径放到系统的Path变量中。
6)push测试报告和测试代码到各自的github仓库
三、思考题:
比较以下二个工匠的做法,你认为哪种好?结合编码和单元测试,谈谈你的认识。
答:我认为工匠一的做法比较好,我们平时在编写程序的时候,总是整面墙都砌完了,直接进行"集成测试",经常让整面的墙倒塌。而在软件项目中,在“砌砖”时以“水平线”为标准,会降低开发与需求理解的偏差、降低开发过程中的缺陷率、并还会提高bug定位速度。测试驱动开发的精髓在于: 将测试方案设计工作提前,在编写代码之前先做这一项工作; 从测试的角度来验证设计,推导设计; 同时将测试方案当作行为的准绳,有效地利用其检验代码编写的每一步,实时验证其正确性,实现软件开发过程的"小步快走"。
四、实验小结
本次实验为单元测试实验,我们小组的命题为生命游戏,使用的语言是c语言,使用的测试工具为PC-lint v9。通过本次实验初步掌握了测试用例的设计方法,掌握了单元测试的方法,学习了PC-lint v9的测试原理及框架;掌握了使用测试框架进行单元测试的方法和过程。
以上是关于实验测试单元的主要内容,如果未能解决你的问题,请参考以下文章