在c++的世界里,程序设计的优雅让位于程序的稳定性、健壮性。“好程序是测出来的”这句话在C++领域里得到了充分体现。下面是我在开发中使用的测试方法,抛砖引玉,和大家交流下。
测试期间,关闭对core文件的限制,使用命令:ulimit -c unlimited
(1)开发阶段
使用cppunit维护测试用例。我一般是用于测试解析类、算法类。
从http://sourceforge.net/projects/cppunit/下载最新版本,解压,看安装文档,一般是./configure & make & make install。
下面举例说明我使用cppunit的方法。假设自己的源码位于src目录下,里面有class1.h/class1.cpp/class2.h/class2.cpp。相对src建立平级目录test存放测试工程,为class1/class2分别建立测试类文件testClass1.h/testClass2.h,建立main函数所在文件test.cpp、makefile。
testClass1.h代码如下,testClass2.h类似。
#include "class1.h"
#include
#include "cppunit/TestRunner.h"
#include "cppunit/TestResult.h"
#include "cppunit/TestResultCollector.h"
#include "cppunit/extensions/HelperMacros.h"
#include "cppunit/BriefTestProgressListener.h"
#include "cppunit/extensions/TestFactoryRegistry.h"
#include "cppunit/TextOutputter.h"
#include "cppunit/CompilerOutputter.h"
#include "cppunit/TestCaller.h"
class testClass1:public CPPUNIT_NS::TestFixture
{
CPPUNIT_TEST_SUITE(testClass1);
CPPUNIT_TEST(testCase1);
CPPUNIT_TEST(testCase2);
CPPUNIT_TEST_SUITE_END();
public:
virtual void setUp(){}
virtual void tearDown(){}
void testCase1()
{
testClass1 a;
a.oper..;
CPPUNIT_ASSERT_EQAL(a.get..,);
}
void testCase2()
{
CPPUNIT_ASSERT(==);
}
};
test.cpp代码如下:
#include "testClass1.h"
#include "testClass2.h"
#include
#include "cppunit/TestRunner.h"
#include "cppunit/TestResult.h"
#include "cppunit/TestResultCollector.h"
#include "cppunit/extensions/HelperMacros.h"
#include "cppunit/BriefTestProgressListener.h"
#include "cppunit/extensions/TestFactoryRegistry.h"
#include "cppunit/TextOutputter.h"
#include "cppunit/CompilerOutputter.h"
#include "cppunit/TestCaller.h"
CPPUNIT_TEST_SUITE_REGISTRATION(testClass1);
CPPUNIT_TEST_SUITE_REGISTRATION(testClass1);
int main()
{
CPPUNIT_NS::TestResult controller;
CPPUNIT_NS::TestResultCollector result;
controller.addListener( &result );
CPPUNIT_NS::TestRunner runner;
runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
runner.run( controller );
CPPUNIT_NS::CompilerOutputter out( &result, std::cout );
out.write();
return 0;
}
makefile文件如下:
EXE=test
SRC=test.cpp
INC_PATH=-I ../src -I (cppunit头文件的目录) -I(依赖的其他头文件路径)
LIB_PATH=-L (cppunit动态库所在的目录) -L (依赖的其他库所在目录)
LIB=-lcppunit -ldl
all:
g++ $(SRC) $(LIB_PATH) $(LIB) $(INC_PATH) -o $(EXE)
再有新的需要测试类,增加相应的测试类,稍微修改下test.cpp即可(增加一句#include,一句CPPUNIT_TEST_SUITE_REGISTRATION)。
保证开发结束后,解析类、算法类等不会有错误。
(2)白盒测试阶段
这个基本是功能逻辑性测试,检测所有数据结构按要求变化以及保证各线程之间变化的一致性。这是最基本也是最全面的一次测试,保证测试的功能覆盖率100%。白盒测试期间可以在代码里加一些宏编译选项或者增加程序交互功能用于观察所有数据结构的变化。
保证测试完毕没有功能性、逻辑性的错误。
(3)内存测试阶段
使用valgrind检测显式内存泄漏、内存读写错误。
从http://www.valgrind.org/下载最新版本,解压,看安装文档,一般是./configure & make & make install。
检测内存一般使用命令valgrind --tool=memcheck -v --leak-check=full ./待测程序错误的地方会用==×××==(×××表示数字)标出。
使用一路模拟客户端做陪测。保证测试完毕,单路客户端陪测的情况下没有任何的显式内存泄漏,没有任何的内存读写错误。
(4)写批量客户端模拟程序
建议熟悉一门方便socket编程的脚本语言,推荐perl。脚本语言简单,实现快速,特适合做陪测。
首先写一个能读取配置文件信息,按配置文件的要求向相应的server,按配置文件的流程发送信令的perl程序。