第一步:将测试代码和实际代码清楚地分隔开。要做到这一步,一个很简单的方法是把所有用来做测试的文件都放到一个特别的目录中去。每个用来做测试的文件的名字都应该以test开头,然后加上它所测试的模块/类名。例如,从testWordTokenizer.cpp文件的名字就可以看出,它是用来测试一个断词类(word tokenizer class)的。
测试用的代码仅在执行测试时才被编译。当生成实际的应用程序时,测试代码会在预处理阶段就被移除。如果我们的每个测试文件都遵循下面的模式就可以保证这一点:
// Test<some_module>.cpp
#ifdef TESTING
/* testing code*/
#endif // TESTING
// End of file
于是,如果定义了TESTING,我们就是在做测试;否则,我们就是在从实际的代码生成应用程序。
第二步:所有用来测试代码片断的函数的名字都应该以Test或test开头。对于你所测试的每个模块/类,都要有一个主测试函数负责调用其他测试函数来测试模块/类的各个代码段。这样你就不需要暴露出所有函数——只要暴露出主测试函数就可以了,像下面的例子:
// TestUrlUtility –用于测试 'Url Utility 函数族'
#if defined( TESTING)
#include "UrlUtility.h"
// 这个命名空间中的函数,从这个源文件外部是不可见的
namespace // 匿名命名空间
{
void TestDivideURL()
{ /* 测试代码 */ }
void TestIsUrlValid()
{ /* 测试代码*/ }
void TestIsHttpUrlValid()
{ /* 测试代码*/ }
void TestParseHttpUrl()
{ /* 测试代码*/ }
}; //匿名命名空间
// ... 这是从这个源文件外部唯一可见的函数
//
// 我们希望暴露出这个函数;
// 在任意文件中,你可以声明它的原型如下:
// void TestUrlUtility();
//
// 然后就可以在你的代码中调用
void TestUrlUtility()
{
TestDivideURL();
TestIsUrlValid();
TestIsHttpUrlValid();
TestParseHttpUrl();
}
#endif // #if defined( TESTING)
// 文件结束