单元测试
单元测试规范
安装
cppunit
cppunit是apache著名的单元测试工具junit的c++版本。
ubuntu安装方式如下:
sudo apt-get install libcppunit-dev
redhat需要下载并编译安装。
valgrind
valgrind是一个著名的内存缺陷检查工具,可以检查并定位内存泄露、越界等问题。
ubuntu安装方式如下:
sudo apt-get install valgrind
规范
概述
- main函数绝对不应当成为测试的地方
- 除了utest目录下,其它所有源码目录都不允许出现测试代码
- 除了utest目录下,其它所有源码目录都不允许出现包含test的文件名。
目录与命名
- 每一个项目都应当包含一个名为utest,并位于项目根目录下的单元测试目录,用于存放 所有的单元测试用例。
- utest目录下只应当有一个cpp文件,名称为project_utest.cpp,project根据不 同项目而异。这是单元测试函数的入口函数。
- 单元测试由于不发布安装,因此所有源码都在头文件中实现,简化开发工作。
- 每个类或模拟类的结构都应当对应一个单元测试类,并位于一个独立的头文件中。
- 单元测试的类名为,要测试的类或模拟类的结构名加上Test后缀。如需要测试的结构为 ImChsLexAnalyzer,则单元测试的类名为ImChsLexAnalyzerTest。
- 每个测试测试的方法,代表了一组测试用例,并以小写test开头。
测试目标
单元测试的目的有两个:
- 发现功能性的问题,如函数的返回不正确。(cppunit)
- 发现内存问题,如内存没有释放。(valgrind)
样例
单元测试入口函数:project_utest
// 被测试的类或结构的头文件 #include "../myproject.h" // cppunit 必须的头文件 #include <cppunit/TestSuite.h> #include <cppunit/TestResult.h> #include <cppunit/TestAssert.h> #include <cppunit/ui/text/TestRunner.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <cppunit/extensions/HelperMacros.h> // 入口函数 int main() { // 宏的参数为需要测试的类名,如有多个类需要测试则写多行。 CPPUNIT_TEST_SUITE_REGISTRATION(ImEmbedJsTest); // 以下代码直到结束,不用做任何修改。 CppUnit::TextUi::TestRunner runner; CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); runner.addTest(registry.makeTest()); runner.run(); return 0; }
测试用例样例:
#ifndef _IM_EMBED_JS_TEST_H_ #define _IM_EMBED_JS_TEST_H_ // 由于cppunit是C++写的,因此在编译C源码的测试用例时,需要加上extern "C"关键词 #ifdef __cplusplus extern "C" { #endif // 需要测试的类或结构名,引用相对路径。 #include <../spider/embedjs/ImEmbedJs.h> #ifdef __cplusplus } #endif // 引入断言宏 #include <cppunit/extensions/HelperMacros.h> #include <iostream> using namespace std; // 修改类名为相应的测试类,类名以被测的类或结构名加上Test class ImEmbedJsTest: public CppUnit::TestFixture { // 宏参数为类名 CPPUNIT_TEST_SUITE(ImEmbedJsTest); // 测试方法,一个方法一行 CPPUNIT_TEST(testScript); CPPUNIT_TEST_SUITE_END(); public: // 数据准备函数,由TestFixture定义,并由测试类override。用以准备测试初始数据。 void setUp() { } // 数据清理函数,由TestFixture定义,并由测试类override。用以清除测试初始数据。 void tearDown() { } // 测试函数,以test开头。用CPPUNIT_ASSERT断言结果是否符合预期。 void testScript() { ImEmbedJs* p_js = ImEmbedJs_new(); char p_content[] = "Published by Justin Wang, Ape Co.ltd,"; ImEmbedJs_init(p_js, p_content); char* lpsz_value; char lpsz_script[] = "function f(){return content.toUpperCase();} f();"; ImEmbedJs_eval(p_js, lpsz_script, strlen(lpsz_script), &lpsz_value); printf("%s\n", lpsz_value); CPPUNIT_ASSERT(strcmp("PUBLISHED BY JUSTIN WANG, APE CO.LTD,", lpsz_value) == 0); free(lpsz_value); ImEmbedJs_delete(p_js); return ; } }; #endif