如果你熟知CppUnit的使用,请参阅我的另一篇文章: CppUnit代码简介 - 第一部分,核心类来获得对于CppUnit进一步的了解。
I. 前言
测试驱动开发是一个现在软件界最流行的词汇之一,可是很多人还是不得其门而入。这篇文章想通过对于CppUnit的介绍,给予读者一个基本的映像。如果你熟知CppUnit的使用,请参阅我的另一篇文章:CppUnit代码简介 - 第一部分,核心类来获得对于CppUnit进一步的了解。
II. 测试驱动开发
要理解测试驱动开发,必须先理解测试。测试就是通过对源代码的运行或者别的方式的检测来确定源代码之中是否含有已知或者未知的错误。所谓测试驱动开发,就是在开发前根据对将要开发的程序的要求,先写好所有测试代码,并且在开发过程中不时地通过运行测试代码来获得所开发的代码与所要求的结果之间的差距。很多人可能会有疑问:既然我还没有开始写代码,我怎么能够写测试代码呢?这是因为,虽然我们还没有写出任何实现代码,但是我们可以根据我们对代码的要求从使用者的角度写出测试代码。事实上,在开发前写出测试代码,可以检测你的要求是不是完善和精确,因为如果你写不出测试代码,表示你的需求还不够清晰。
这篇文章通过一个文件状态操作类来展示测试驱动开发相对于普通开发方法的优势。
III. 文件状态操作类(FileStatus)需求
构造函数,接受一个const std::string&作为文件名参数。
DWORD getFileSize()函数,获取这个文件的长度。
bool fileExists()函数,获取这个文件是否存在。
void setFileModifyDate(FILETIME ft)函数,设定这个文件的修改日期。
FILETIME getFileModifyDate()函数,返回这个文件的修改日期。
std::string getFileName()函数,返回这个文件的名字。
IV. CppUnit简介
我们所进行的测试,某种意义上说,就是一个或者多个函数。通过对这些函数的运行,我们可以检测我们是否有错误。假设我们要对构造函数和getFileName函数进行测试,这里面有一个很显然的不变式,就是对一个FileStatus::getFileName函数的调用,应该与传给这个FileStatus对象的构造函数的参数相同。于是我们有这样一个函数:
bool testCtorAndGetFileName()
{
const string fileName( "a.dat" );
FileStatus status( fileName );
return ( status.getFileName() == fileName );
}
我们只需要测试这个函数的返回值就可以知道是否正确了。在CppUnit中,我们可以从TestCase派生出一个类,并且重载它的runTest函数。
class MyTestCase:public CPPUNIT_NS::TestCase
{
public:
virtual void runTest()
{
const std::string fileName( "a.dat" );
FileStatus status( fileName );
CPPUNIT_ASSERT_EQUAL( status.getFileName(), fileName );
}
};
CPPUNIT_ASSERT_EQUAL是一个宏,在它的两个参数不相等的时候,会抛出异常。所以,理论上说,我们可以通过:
MyTestCase m;
m.runTest();
文章来源于领测软件测试网 https://www.ltesting.net/