linux unittest cpp,Linux下cppunit的基本使用说明文档及项目测试简介

Cppunit使用说明文档

注:此文档部分内容来源于cppunit源码解读,以及https://www.ibm.com/developerworks/cn/linux/l-cppunit/index.html与http://blog.csdn.net/freefalcon/article/details/753819参照该文档可以更好的理解cppunit的使用,无耻的加了原创

一、CppUnit核心内容主要包括六个方面:

1.测试对象(Test,TestFixture,…):用于开发测试用例,以及对测试用例进行组织管理。

2.测试结果(TestResult):处理测试用例执行结果。TestResult与下面的TestListener采用的是观察者模式 (Observer Pattern)。

3.测试结果监听者(TestListener):TestListener作为TestResult的观察者,担任实际的结果处理角色。

4.结果输出(Outputter):将结果进行输出,可以制定不同的输出格式。

5.对象工厂(TestFactory):用于创建测试对象,对测试用例进行自动化管理。

6.测试执行体(TestRunner):用于运行一个测试。

二、各模块的主要类继承结构

6ea55b06670b041df368c51692077f1c.png

三、CppUnit的原理

​ 在CppUnit中,一个或一组测试用例的测试对象被称为Fixture。Fixture就是被测试的目标,可能是一个对象或者一组相关的对象,甚至一个函数。(在此Fixture为下述函数中的GetAmount及GetCurrency)

​ 有了被测试的 fixture,就可以对这个fixture 的某个功能、某个可能出错的流程编写测试代码,这样对某个方面完整的测试被称为TestCase(测试用例)。通常写一个 TestCase 的步骤包括:

(1).对 fixture 进行初始化,及其他初始化操作,比如:生成一组被测试的对象,初始化值;

(2).按照要测试的某个功能或者某个流程对 fixture 进行操作;

(3).验证结果是否正确;

(4).对fixture 的及其他的资源释放等清理工作。

​ 对 fixture 的多个测试用例,通常(1)、(4)部分代码都是相似的,CppUnit 在很多地方引入了 setUp 和 tearDown 虚函数。可以在 setUp 函数里完成(1)初始化代码,而在 tearDown 函数中完成(4)代码。具体测试用例函数中只需要完成(2)(3)部分代码即可,运行时 CppUnit 会自动为每个测试用例函数运行 setUp,之后运行 tearDown,这样测试用例之间就没有交叉影响。

​ 对 fixture 的所有测试用例可以被封装在一个 CppUnit::TestFixture 的子类(命名惯例是[ClassName]Test)中。然后定义这个fixture 的 setUp 和 tearDown 函数,为每个测试用例定义一个测试函数(命名惯例是 testXXX)

​ 要把对 fixture 的一个测试函数转变成一个测试用例,需要生成一个 CppUnit::TestCaller 对象。而最终运行整个应用程序的测试代码的时候,可能需要同时运行对一个 fixture 的多个测试函数,甚至多个 fixture 的测试用例。CppUnit 中把这种同时运行的测试案例的集合称为 TestSuite。而 TestRunner 则运行测试用例或者 TestSuite,具体管理所有测试用例的生命周期。目前提供了 3 类TestRunner,包括:

CppUnit::TextUi::TestRunner // 文本方式的TestRunner,下述例子为文本方式

CppUnit::QtUi::TestRunner // QT方式的TestRunner

CppUnit::MfcUi::TestRunner // MFC方式的TestRunner

四、验证测试结果的方式

// 确信condition为真

CPPUNIT_ASSERT(condition)

// 当condition为假时失败, 并打印message

CPPUNIT_ASSERT_MESSAGE(message, condition)

// 当前测试失败, 并打印message

CPPUNIT_FAIL(message)

// 确信两者相等

CPPUNIT_ASSERT_EQUAL(expected, actual)

// 失败的同时打印message

CPPUNIT_ASSERT_EQUAL_MESSAGE(message, expected, actual)

// 当expected和actual之间差大于delta时失败

CPPUNIT_ASSERT_DOUBLES_EQUAL(expected, actual, delta)

// 判断执行表达式expression后是否抛出ExceptionType异常

CPPUNIT_ASSERT_THROW(expression, ExceptionType)

// 执行表达式expression后无异常抛出

CPPUNIT_ASSERT_NO_THROW(expression)

五、测试结果输出方式

测试结果输出有三种,链接如下

https://www.ibm.com/developerworks/cn/linux/l-cppunit/index.html

此例用的是xml的输出方式,以xml输出的核心部分如下:

std::ofstream xmlFileOut("cpptestresults.xml");

CppUnit::XmlOutputter xmlOut(&result, xmlFileOut);

xmlOut.write(); //将结果写入xml

xmlFileOut.close();

六、代码如下

一、被测代码

1、Money.h

#ifndef _MONEY_H

#define _MONEY_H

#include

#include

using namespace std;

class CMoney

{

public:

CMoney( double amount, string currency )

: m_amount( amount )

, m_currency( currency )

{

}

~CMoney(){}

double GetAmount() const;

string GetCurrency() const;

private:

double m_amount;

string m_currency;

};

#endif

2、Money.cpp

#include

#include

#include "Money.h"

using namespace std;

double CMoney::GetAmount() const

{

return m_amount;

}

string CMoney::GetCurrency() const

{

return m_currency;

}

二、测试代码

1、Money_Test.h

#ifndef _MONEY_TEST_H

#define _MONEY_TEST_H

#include "cppunit/extensions/HelperMacros.h"

#include "Money.h"

class CMoneyTest:public CppUnit::TestFixture

{

/*声明一个TestSuite*/

CPPUNIT_TEST_SUITE(CMoneyTest);

/*添加测试用例到TestSuite,定义新的测试用例都要在这里声明;

* 如果此处未声明某个测试用例,程序编译和运行都不会报错

* 仅仅是该测试用例不会被执行。

*/

CPPUNIT_TEST(testConstructor);

CPPUNIT_TEST(testOptorEqual);

CPPUNIT_TEST(testOptorNotEqual);

CPPUNIT_TEST(testOptorAdd);

/*TestSuite声明完成*/

CPPUNIT_TEST_SUITE_END();

public:

CMoneyTest(){}

/*初始化 */

void setUp();

/*清除动作 */

void tearDown();

/*test app in Money.cpp*/

/*test case */

void testConstructor();

};

#endif

2、Money_Test.cpp

#include "Money_Test.h"

#include "Money.h"

#include

using namespace std;

/* 将该TestSuite注册到名字为“alltest”的TestSuite中,如果未定义会自动定义,也可以使用CPPUNIT_TEST_SUITE_REGISTRATION( MathTest );定义到全局未命名的TestSuite中 */

CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(CMoneyTest,"alltest");

/*初始化动作*/

void CMoneyTest::setUp()

{

}

/*清除动作*/

void CMoneyTest::tearDown()

{

}

/*编写测试用例,

* 此处编写一个用例分别来测试CMoney类的一个成员函数

* 如果有其他测试用例,继续添加即可

*/

/*test app in Money.cpp*/

/*test constructor*/

void CMoneyTest::testConstructor()

{

double dNum = 22124.44;

string sCurrency = "DD";

CMoney MyMoney(dNum, sCurrency);

CPPUNIT_ASSERT_EQUAL(dNum, MyMoney.GetAmount());

CPPUNIT_ASSERT_EQUAL(sCurrency, MyMoney.GetCurrency());

}

3、Money_Test_Main.cpp

#include

#include

#include

#include

#include

int main()

{

CppUnit::TestResult controller; //测试结果

CppUnit::TestResultCollector result; //收集结果

controller.addListener( &result ); //监听

CppUnit::TextUi::TestRunner runner; //测试文本类型

/*从注册的TestSuite获取特定的TestSuite,

没有参数的话则获取未命名的TestSuite*/

CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry("alltest");

/*添加这个TestSuite到TestRunner中*/

runner.addTest(registry.makeTest());

/*运行测试*/

runner.run( controller );

std::ofstream xmlFileOut("cpptestresults.xml"); //构造输出文件流

CppUnit::XmlOutputter xmlOut(&result, xmlFileOut);

xmlOut.write(); //将结果写入xml

xmlFileOut.close();

return 0;

}

七、编译

1、g++ -lcppunit -ldl -o test Money_main.cpp Money_Test.cpp Money.cpp

2、如果是多文件项目,请编写makefile(可以根据原来的makefile微调即可,主要调整包含cpp的部分),并添加-lcppunit -ldl

八、其他

什么叫做桩代码(测试桩),简而言之就是代替某些代码的代码。

如果测试中小型项目,只需把注册名字统一,然后不同类可以用不同cpp文件测试

目前暂时想到这么多,如后续遇到问题再补充,我们只能尽可能的多想到问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值