正如大家所知道的,好的测试应具备如下的品质
§ A-TRIP(automatic,Thorough,Repeatable,Independent,Professional)
§ 自动化的:借鉴持续构建和测试的方法。参考Cruise Control
§ 彻底的:如NCover工具。
§ 可重复的:使用mock对象隔离外界因素。
§ 独立的:每个测试都有setup和tear down函数,每个测试应该是独立的孤岛,不依赖其他测试。
§ 专业的:提取公共部分。数据驱动的测试(数据与代码分离)
在用单元测试工具进行测试时,测试数据与测试程序的分离。
测试数据保存在excel中,举例如下:
fucName |
expectedResult |
param1 |
param2 |
param3 |
param4 |
start |
1 |
0 |
0 |
0 |
0 |
start |
-4 |
4 |
0 |
0 |
0 |
start |
-1 |
0 |
4 |
0 |
0 |
SetHue |
1 |
0 |
30 |
0 |
|
SetHue |
-2 |
0 |
30 |
-5 |
|
SetHue |
-4 |
4 |
0 |
0 |
|
1.1
根据经验,测试程序的颗粒划分要小,如对于同一个函数的一组非法参数的测试,要放在不同的测试程序中进行,如果一个测试程序执行了一组的,那么如有有一个非法参数失败,那么会导致其余非法参数没有运行。这样就可能需要手工屏蔽失败的非法参数,就不能实现完全的自动化。
这里,通过dll的方式导出了4个函数,这里为了清楚,把参数,返回值记录如下:
bool EnumSpecialFunction( char * functionname, std::vector<StartParameters> & result )
BOOL InitExcelObject ()
BOOL UninitExcelObject ( void )
BOOL ReadExcel ( int row, int col, char * cellmsg )
其中,EnumSpecialFunction的参数1为待测试的函数名称,如果和excel中的fucName名称相同的所有行数,都会通过参数2 result返回。例如调用EnumSpecialFunction("SetHue", data )时,参数1输入SetHue,data返回如下数据:
SetHue |
1 |
0 |
30 |
0 |
SetHue |
-2 |
0 |
30 |
-5 |
SetHue |
-4 |
4 |
0 |
0 |
1.2
通过data【0】得到第一组数据,data【1】得到第二组数据,依此类推。
那么,如何使用导出的函数进行测试那?
第一,要将excel类添加到工程中。
在ClassWizard中,【Add Class】,在Excel的安装目录找到Excel.exe(Microsoft2003是Excel.exe;2007应该又独立的lib库,这个没有验证),添加必要的几个类:
// Excel应用对象
_Application m_oExcelApp; // Excel程序
_Worksheet m_oWorkSheet; // 工作表
_Workbook m_oWorkBook; // 工作簿
Workbooks m_oWorkBooks; // 工作簿集合
Range m_oCurrRange; // 使用区域
Worksheets m_oWorkSheets; // 工作表集合
第二,在工程下,new一个头文件,例如,命名为EnumDll,声明如下内容:
typedef struct
{
char fuctionname[50];
int expectedResult;
int a;
int b;
int c;
int d;
// int fuctionid;
}StartParameters;
BOOL InitExcelObject ( /*CString strFilePath*/ );
BOOL UninitExcelObject ( void );
BOOL ReadExcel ( int row, int col, char * cellmsg );
bool EnumSpecialFunction( char * functionname, std::vector<StartParameters> & result );
这里,用了STL(standard template library)的容器vector.
在一些使用 MFC 的程序中,经常看到许多程序使用 CArray<>,由于 CArray<>的设计问题,造成使用它的代码的复杂化,增加了维护难度。因此建议使用 ::std::vector<> 代替 CArray<>。另外,也看到一些程序在用 malloc/realloc/free/new[]/delete[] 等手工管理内存。在应用程序中,手工管理内存是容易导致错误的,应该用 ::std::vector<> 之类的对象来管理动态数组。如果用数组的话,需要手动释放,vector的话,不是指针的,就会自己在析构函数中释放.所以这里用了vector。个人比较喜欢用STL提供的容器,记得使用时,添加对应的头文件啊。这里不详细介绍了。
第三,在工程的头文件中,需要添加:
#include <vector>
#include "../EnumDll.h"
第四,在工程路径下,copy dllEnumSpecialFunction.lib与dllEnumSpecialFunction.dll,并新建一个名称为Demo.xls的excel文件作为测试程序要读取的测试数据,格式如1。1所示。在project setting/link下把dllEnumSpecialFunction.lib添加进来。
第五,在cppunit的测试框架下,当然,其他测试框架也可以,在测试程序中,在setUp函数中,调用dll导出的函数EnumSpecialFunction,这里函数名称为start,如下代码:
char functionname[] = "start";
void SampleTest::setUp()
{
EnumSpecialFunction( functionname, data );
}
在要测试start函数的testcase中,如testStart1函数中,调用如下即可:
void SampleTest::testStart1()
{
int resstart = 0;
StartParameters startparam = data[0];
resstart = start( startparam.a, startparam.b, startparam.c, startparam.d );
CPPUNIT_ASSERT( startparam.expectedResult==resstart );
}
类似,可以通过给EnumSpecialFunction函数输入不同的函数名称测试不同的函数,通过data[0],data[n]来选择执行excel中的某组测试。
如果有人需要dll,可以留言,我会发给大家啊。别担心,完全免费的!!
另,该dll也提供了write excel的函数,来写测试报告到excel中。
下篇将详细介绍基于cppunit的测试报告在excel的生成,也是基于我写的dll的哦。