单元测试

单元测试规范

安装

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 &registry =
                        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
posted @ 2011-06-02 18:12  wangkangluo1  阅读(644)  评论(0编辑  收藏  举报