一个好的开发工具能够极大的提高工作效率,而好的开发工具是智慧与努力的结晶。
这里包括2个宏:CppUnitTest_CreateSuite和CppUnitTest_CreateMain
CppUnitTest_CreateMain用来产生单元测试主框架,产生的文件为alltest.cpp,如下:
#include <cppunit/extensions/TestFactoryRegistry.h> #include <cppunit/ui/text/TestRunner.h> int main(int argc, char** argv) { CppUnit::TextUi::TestRunner runner ; // 从注册的TestSuite中获取特定的TestSuite, 没有参数获取未命名的TestSuite. CppUnit::TestFactoryRegistry& registry = CppUnit::TestFactoryRegistry::getRegistry("alltest") ; // 添加这个TestSuite到TestRunner中 runner.addTest( registry.makeTest() ) ; // 运行测试 runner.run() ; }
CppUnitTest_CreateSuite宏用法:
1、定义一个类(头文件、源文件),并定义好基本的方法或函数(参数、返回值任意);
2、打开定义的源文件,执行此宏;
3、稍后,选择单元测试保存的路径;
4、手动修改、添加测试数据等。
局限:
1、此宏是针对源文件而写,如果在头文件中也可以,自己可以修改一下:使用前文讲的切换宏,首先从头文件切换到源文件即可,当前如果在头文件中执行,只产生了基本的结构,针对每个自定义函数需要自己写对应的测试函数。
2、对于重载函数并没有区分,需要再手动更改。
首先看一下宏运行后的效果:
定义的头文件:
#ifndef XXXXX_H #define XXXXX_H class CXXXXXX { public: CXXXXXX(); ~CXXXXXX(); void XXXXX1(int n); void XXXXX1(double f) ; int XXXXX2(void); void* XXXXX3(int array[]); }; #endif
定义的源文件:
#include "test.h" CXXXXXX::CXXXXXX() { } CXXXXXX::~CXXXXXX() { } void CXXXXXX::XXXXX1(int n) { // ..... } void CXXXXXX::XXXXX1(double f) { // ..... } int CXXXXXX::XXXXX2(int n) { // ..... } void CXXXXXX::XXXXX3(int array[]) { // ..... }
#ifndef _CXXXXXX_TEST_H_ #define _CXXXXXX_TEST_H_ #include "cppunit/extensions/HelperMacros.h" class CXXXXXXTest: public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(CXXXXXXTest); CPPUNIT_TEST(XXXXX1Test); CPPUNIT_TEST(XXXXX1Test); CPPUNIT_TEST(XXXXX2Test); CPPUNIT_TEST(XXXXX3Test); CPPUNIT_TEST_SUITE_END(); public: CXXXXXXTest(); ~CXXXXXXTest(); void setUp(); void tearDown(); void XXXXX1Test(void); void XXXXX1Test(void); void XXXXX2Test(void); void XXXXX3Test(void); private: /*add internal unit test functions and variables here*/ }; #endif
#include "CXXXXXXTest.h" #include "CXXXXXX.h" CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(CXXXXXXTest, "alltest" ); void CXXXXXXTest::CXXXXXXTest() { /* 构造函数 */ } void CXXXXXXTest::~CXXXXXXTest() { /* 析构函数 */ } void CXXXXXXTest::setUp() { /* initiation */ } void CXXXXXXTest::tearDown() { /* release resources */ } void CXXXXXXTest::XXXXX1Test() { CXXXXXX obj ; obj.XXXXX1() ; } void CXXXXXXTest::XXXXX1Test() { CXXXXXX obj ; obj.XXXXX1() ; } void CXXXXXXTest::XXXXX2Test() { CXXXXXX obj ; obj.XXXXX2() ; } void CXXXXXXTest::XXXXX3Test() { CXXXXXX obj ; obj.XXXXX3() ; }
宏代码:
/** 创建CPPUnit单元测试自动生成工具,通常情况下,类定义完成后,在CPP中执行此宏 作者: 王丰亮 时间: 2012.02.18 */ macro CppUnitTest_CreateSuite() { hbuf = GetCurrentBuf() isymMax = GetBufSymCount (hbuf) isym = 0 while (isym < isymMax) { symbolname = GetBufSymName (hbuf, isym) //Msg(symname) symbol = GetSymbolLocation(symbolname) if (symbol == nil) { //Msg (symbolname # " was not found") } else if(symbol.Type == "Class") { // 判断是否以"Test"结尾 strEnd = strmid (symbolname, strlen(symbolname)-strlen("Test"), strlen(symbolname)) if(toupper(strEnd) == toupper("Test")) { Msg(cat(cat("Detect the classname \"", symbolname), "\" end with \"Test\", maybe it's already a TestSuit, Continue anyway?")) } hTmpTestBuf = NewBuf("ClassInfo") //Msg(symbolname) AppendBufLine(hTmpTestBuf, symbolname) // 类名 // 匹配成员函数 //Msg(symbol.Symbol) patternExp = cat(symbolname, "::.+(") //SearchInBuf (hbuf, pattern, lnStart, ichStart, fMatchCase, fRegExp, fWholeWordsOnly) sSel = SearchInBuf (hbuf, patternExp, 0, 0, False, True, False) while(sSel != nil) { strFuncName = strmid(GetBufLine(hbuf, sSel.lnFirst), sSel.ichFirst+strlen(symbolname)+2, sSel.ichLim-1) //Msg(strFunName) if(strFuncName != symbolname) // 构造函数 { if(strFuncName != cat("~", symbolname)) // 析构函数 { AppendBufLine(hTmpTestBuf, strFuncName) // 普通函数 } } sSel = SearchInBuf (hbuf, patternExp, sSel.lnFirst+1, 0, False, True, False) } CreateCppUnitTestFiles(hTmpTestBuf) CloseBuf(hTmpTestBuf) } isym = isym + 1 } } macro CreateCppUnitTestFiles(hTmpTestBuf) { if(hTmpTestBuf == hNil) stop curLine = 0 strClassNameOrig = GetBufLine(hTmpTestBuf, curLine) strClassName = cat(strClassNameOrig, "Test") hUnitTestHeaderBuf = NewBuf(cat(strClassName, ".h")) hUnitTestSourceBuf = NewBuf(cat(strClassName, ".cpp")) if(hUnitTestHeaderBuf == hNil) stop if(hUnitTestSourceBuf == hNil) stop // 头文件 AppendBufLine(hUnitTestHeaderBuf, cat(cat("#ifndef _", toupper(strClassNameOrig)), "_TEST_H_") ) AppendBufLine(hUnitTestHeaderBuf, cat(cat("#define _", toupper(strClassNameOrig)), "_TEST_H_") ) AppendBufLine(hUnitTestHeaderBuf, "") AppendBufLine(hUnitTestHeaderBuf, "#include \"cppunit/extensions/HelperMacros.h\"" ) AppendBufLine(hUnitTestHeaderBuf, "") AppendBufLine(hUnitTestHeaderBuf, cat(cat("class ", strClassName), ": public CppUnit::TestFixture") AppendBufLine(hUnitTestHeaderBuf, "{") //AppendBufLine(hUnitTestHeaderBuf, "") AppendBufLine(hUnitTestHeaderBuf, cat(cat(" CPPUNIT_TEST_SUITE(", strClassName), ");") ) // 源文件 AppendBufLine(hUnitTestSourceBuf, cat(cat("#include \"", cat(strClassName, ".h")), "\"") ) AppendBufLine(hUnitTestSourceBuf, cat(cat("#include \"", cat(strClassNameOrig, ".h")), "\"") ) AppendBufLine(hUnitTestSourceBuf, "") AppendBufLine(hUnitTestSourceBuf, cat(cat("CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(", strClassName), ", \"alltest\" );")) AppendBufLine(hUnitTestSourceBuf, "") AppendBufLine(hUnitTestSourceBuf, cat(cat(cat("", strClassName), "::"), cat(strClassName, "()")) AppendBufLine(hUnitTestSourceBuf, "{") AppendBufLine(hUnitTestSourceBuf, " /* 构造函数 */") AppendBufLine(hUnitTestSourceBuf, "}") AppendBufLine(hUnitTestSourceBuf, "") AppendBufLine(hUnitTestSourceBuf, cat(cat(cat("", strClassName), "::~"), cat(strClassName, "()")) AppendBufLine(hUnitTestSourceBuf, "{") AppendBufLine(hUnitTestSourceBuf, " /* 析构函数 */") AppendBufLine(hUnitTestSourceBuf, "}") AppendBufLine(hUnitTestSourceBuf, "") AppendBufLine(hUnitTestSourceBuf, cat(cat("void ", strClassName), "::setUp()")) AppendBufLine(hUnitTestSourceBuf, "{") AppendBufLine(hUnitTestSourceBuf, " /* initiation */") AppendBufLine(hUnitTestSourceBuf, "}") AppendBufLine(hUnitTestSourceBuf, "") AppendBufLine(hUnitTestSourceBuf, cat(cat("void ", strClassName), "::tearDown()")) AppendBufLine(hUnitTestSourceBuf, "{") AppendBufLine(hUnitTestSourceBuf, " /* release resources */") AppendBufLine(hUnitTestSourceBuf, "}") AppendBufLine(hUnitTestSourceBuf, "") curLine = 1 lines = GetBufLineCount(hTmpTestBuf) while(curLine < lines) { strFuncNameOrig = GetBufLine(hTmpTestBuf, curLine) strFuncName = cat(strFuncNameOrig, "Test") // 头文件测试函数宏 AppendBufLine(hUnitTestHeaderBuf, cat(cat(" CPPUNIT_TEST(", strFuncName), ");") ) curLine = curLine + 1 } AppendBufLine(hUnitTestHeaderBuf, " CPPUNIT_TEST_SUITE_END();" ) AppendBufLine(hUnitTestHeaderBuf, "") AppendBufLine(hUnitTestHeaderBuf, "public:") AppendBufLine(hUnitTestHeaderBuf, cat(cat(" ", strClassName), "();")) AppendBufLine(hUnitTestHeaderBuf, cat(cat(" ~", strClassName), "();")) AppendBufLine(hUnitTestHeaderBuf, "") AppendBufLine(hUnitTestHeaderBuf, " void setUp();") AppendBufLine(hUnitTestHeaderBuf, " void tearDown();") AppendBufLine(hUnitTestHeaderBuf, "") curLine = 1 //lines = GetBufLineCount(hTmpTestBuf) while(curLine < lines) { strFuncNameOrig = GetBufLine(hTmpTestBuf, curLine) strFuncName = cat(strFuncNameOrig, "Test") // 头文件测试函数声明 AppendBufLine(hUnitTestHeaderBuf, cat(cat(" void ", strFuncName), "();") ) // 源文件测试函数定义 AppendBufLine(hUnitTestSourceBuf, cat(cat("void ", strClassName), cat("::", cat(strFuncName,"()")))) AppendBufLine(hUnitTestSourceBuf, "{") AppendBufLine(hUnitTestSourceBuf, cat(cat(" ", strClassNameOrig), " obj ;")) AppendBufLine(hUnitTestSourceBuf, cat(cat(" obj.", strFuncNameOrig), "() ;")) AppendBufLine(hUnitTestSourceBuf, "}") AppendBufLine(hUnitTestSourceBuf, "") curLine = curLine + 1 } AppendBufLine(hUnitTestHeaderBuf, "") AppendBufLine(hUnitTestHeaderBuf, "private:") AppendBufLine(hUnitTestHeaderBuf, "") AppendBufLine(hUnitTestHeaderBuf, " /*add internal unit test functions and variables here*/") AppendBufLine(hUnitTestHeaderBuf, "") AppendBufLine(hUnitTestHeaderBuf, "};") AppendBufLine(hUnitTestHeaderBuf, "#endif") SaveBuf(hUnitTestHeaderBuf) SaveBuf(hUnitTestSourceBuf) } macro CppUnitTest_CreateMain() { hUnitTestMainBuf = NewBuf("alltest.cpp") if(hUnitTestMainBuf == nil) stop // 单元测试main.cpp AppendBufLine(hUnitTestMainBuf, "#include <cppunit/extensions/TestFactoryRegistry.h>" ) AppendBufLine(hUnitTestMainBuf, "#include <cppunit/ui/text/TestRunner.h>" ) AppendBufLine(hUnitTestMainBuf, "") AppendBufLine(hUnitTestMainBuf, "int main(int argc, char** argv)" ) AppendBufLine(hUnitTestMainBuf, "{") AppendBufLine(hUnitTestMainBuf, " CppUnit::TextUi::TestRunner runner ;" ) AppendBufLine(hUnitTestMainBuf, "") AppendBufLine(hUnitTestMainBuf, " // 从注册的TestSuite中获取特定的TestSuite, 没有参数获取未命名的TestSuite.") AppendBufLine(hUnitTestMainBuf, " CppUnit::TestFactoryRegistry& registry = CppUnit::TestFactoryRegistry::getRegistry(\"alltest\") ;") AppendBufLine(hUnitTestMainBuf, " // 添加这个TestSuite到TestRunner中") AppendBufLine(hUnitTestMainBuf, " runner.addTest( registry.makeTest() ) ;") AppendBufLine(hUnitTestMainBuf, "") AppendBufLine(hUnitTestMainBuf, " // 运行测试") AppendBufLine(hUnitTestMainBuf, " runner.run() ;") AppendBufLine(hUnitTestMainBuf, "") AppendBufLine(hUnitTestMainBuf, "}") // AppendBufLine(hUnitTestMainBuf, "") SaveBuf(hUnitTestMainBuf) }