您的位置:首页 > 运维架构 > Linux

在LINUX中CppUnit应用指南

2012-01-12 15:13 281 查看
l 在LINUX中CppUnit应用指南

目 录
1 引言... 4

1.1 摘要... 4

1.2 术语、定义和缩略语... 4

1.3 安装CppUnit 4

2 建立CppUnit测试用例... 4

2.1 建立一个被测函数... 4

2.2 建立一个简单的测试用例... 5

2.3 使用TestSuite. 6

2.4 使用TestRunner 7

2.5 使用宏... 7

2.6 编译该测试文件... 8

3 备注... 8

1 引言

1.1 摘要

简单描述CppUnit在Linux系统下的使用方法,以便在单元测试过程中能够提高正确率和效率。本文仅仅是把一部分英文的说明文档写成中文的。

1.2 术语、定义和缩略语

序号
术语或缩略语
说明性定义
1
CppUnit
一个用于单元测试的开源软件

2

1.3 安装CppUnit

首先,需要到这个(http://sourceforge.net/project/showfiles.php?group_id=11795)地址下载一个CppUnit安装程序。该地址不仅有CppUnit安装程序,还有CppUnit的说明文档。本文以CppUnit1.12.0版进行说明。

有了压缩包了,就可以进行解压缩安装了,在压缩包所在目录下执行如下命令:

tar –xzfcppunit-1.12.0.tar.gz

cd cppunit-1.12.0

./configure

make

make check

make install

几乎每条命令都要执行几分钟。到此就已经完成安装了。

如果写好程序后进行编译,编译器报告没有库文件,则需要把/usr/local/lib下和cppunit有关的几个库文件拷贝到/usr/lib目录下。

2 建立CppUnit测试用例

2.1 建立一个被测函数

class Complex

{

friendint operator==(const Complex &a, const Complex &b);

friendComplex operator+(const Complex &a, const Complex &b);

doublereal, imaginary;

public:

Complex(doubler, double i = 0):real(r), imaginary(i){}

};

int operator==(const Complex &a, constComplex &b)

{

return(int)(a.real==b.real && a.imaginary==b.imaginary);

}

Complex operator+(const Complex &a,const Complex &b)

{

Complexc(0, 0);

c.real= a.real+b.real;

c.imaginary= a.imaginary+b.imaginary;

returnc;

}

假设Complex就是即将要测试的类,测试两个运算符重载。

2.2 建立一个简单的测试用例

建立CppUnit测试类,需要继承TestCase类。我们需要作的主要就是重写setUp()和tearDown()函数,并根据被测函数写测试函数。其中,setUp()函数主要用于初始化变量;tearDown()做善后处理,一般用于释放堆空间。OK,让我们写一个简单的测试类。

class ComplexNumberTest:publicCppUnit::TestCase

{

private:

Complex*m_10_1, *m_1_1, *m_11_2;

public:

voidsetUp();

voidtearDown();

voidtestEquality();

voidtestAddition();

};

void ComplexNumberTest::setUp()

{

m_10_1= new Complex(10, 1);

m_1_1= new Complex(1, 1);

m_11_2= new Complex(11, 2);

}

void ComplexNumberTest::tearDown()

{

deletem_10_1;

m_10_1= NULL;

deletem_1_1;

m_1_1= NULL;

deletem_11_2;

m_11_2= NULL;

}

///测试函数operator==()

void ComplexNumberTest::testEquality()

{

CPPUNIT_ASSERT(*m_10_1== *m_10_1);

CPPUNIT_ASSERT(!(*m_10_1== *m_11_2));

}

///测试函数operator+()

void ComplexNumberTest::testAddition()

{

CPPUNIT_ASSERT(*m_10_1+*m_1_1== *m_11_2);

}

函数都写好了,其中CPPUNIT_ASSERT()是一个类似于断言的宏定义,根据括号内的逻辑语句是true或false得出不同的结果,至于所得结果的用法,下面介绍。

需要注意的是,不要自作聪明的给这个类加入构造函数、复制构造函数、赋值函数。任何不必要的函数都会让程序编译不过去。

2.3 使用TestSuite

你不希望用上小节的类,一条一条的在main函数中调用执行吧?这样的工作量将大的惊人。我们有更好的办法,把它们都加入到一个TestSuite中,直接执行这个suite的run()成员函数就可以了,下面是加入方法:

CppUnit::TestSuitesuite;

CppUnit::TestResultresult;

suite.addTest(newCppUnit::TestCaller<ComplexNumberTest>(

“testEquality”,

&ComplexNumberTest::testEquality));

suite.addTest(newCppUnit::TestCaller<ComplexNumberTest>(

“testAddition”,

&ComplexNumberTest::testAddtion));

suite.run(&result);

首先定义一个suite,然后定义一个result,result用于接收测试的执行结果。

用addTest()函数来添加测试用例,尖括号中是测试类。内层圆括号的第一个参数是一个字符串,当测试出现异常时,将输出这个字符串,以表示该部分的测试不成功;第二个参数是测试类中函数的地址。其他部分照搬。

执行run(&result)函数。这样还不可以,虽然测试函数被执行了,但无法得到任何结果。如果是这样执行,我们得到的仅仅是CppUnit这个软件工作正常,要想得到软件的测试结果,还要用到下一小节介绍的一个类。

2.4 使用TestRunner

我们接下来要做的就是,把上小节的代码段装到一个成员函数中。需要在测试类中以静态方式定义该函数。我们在ComplexNumberTest类中加入如下函数:

staticCppUnit::Test* suite()

{

CppUnit::TestSuite *suiteOfTests = newCppUnit::TestSuite("ComplexNumberTest");

suiteOfTests->addTest(newCppUnit::TestCaller<ComplexNumberTest>

("testEquality",&ComplexNumberTest::testEquality));

suiteOfTests->addTest(newCppUnit::TestCaller<ComplexNumberTest>

("testAddition",&ComplexNumberTest::testAddition));

return suiteOfTests;

}

可以看出,这里没有用到result,也没有执行run()函数,而是直接返回的suite对象。用TestRunner对象来接受静态函数的返回值就可以了。主函数如下:

intmain()

{

CppUnit::TextUi::TestRunner runner;

runner.addTest(ComplexNumberTest::suite());

runner.run();

return 0;

}

主函数中首先定义了一个runner对象,用该对象的addTest()函数把suite()函数加入到runner对象中,执行run()函数。该runner.run()函数不仅有suite.run()函数的功能,还能给出输出结果,报告测试成功还是测试出错以及出错的位置。

2.5 使用宏

有一种更简单的方法可以替代2.3小节的代码,那就是使用宏。我们可以把ComplexNumberTest中的静态函数suite()删除,用以下四条宏语句来代替这个函数:

CPPUNIT_TEST_SUITE(ComplexNumberTest);

CPPUNIT_TEST(testEquality);

CPPUNIT_TEST(testAddition);

CPPUNIT_TEST_SUITE_END();

其中,第一条宏的参数是测试类的名字,中间两条宏的参数是测试函数,有多少个测试函数,就要有多少个CPPUNIT_TEST()宏。最后一条宏是与第一条配对的。

除此之外,还有许多可用的宏,比如需要测试一个函数是否能够抛出异常,可以用宏CPPUNIT_TEST_EXCEPTION(testMethod,ExceptionType),其中testMethod是测试函数,ExceptionType是异常类型;测试一个函数是否会失败,可以用CPPUNIT_TEST_FAIL(testMethod),这个宏与CPPUNIT_TEST()做相反的操作。

2.6 编译该测试文件

把以上代码复制粘贴到一个cpp文件中进行编译还不能通过,需要引入如下头文件:

#include<cppunit/TestRunner.h>

#include<cppunit/TestResult.h>

#include<cppunit/extensions/HelperMacros.h>

#include<cppunit/ui/text/TestRunner.h>

编译时,需要引用两个库文件,可以用如下命令进行编译:

g++mytest.cpp –o mytest –lcppunit –ldl

命令中,mytest.cpp为源文件,mytest为目标文件,cppunit和dl为库文件。

3 备注

如果想了解CppUnit更多的内容,可以到如下地址下载官方文档http://sourceforge.net/project/showfiles.php?group_id=11795

本文作者:甜菜晒干了。如果有什么错漏之处,请与我联系:daobanyemi@sina.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐