CxxTest简介和特性
1. 简介
CxxTest是C++语言的一个框架,它的风格类似于JUnit/CppUnit/xUnit。与已有的替代解决方案相比,它具有如下一些优点:
• 不需要RTTI。
• 不需要成员模板功能。
• 不需要异常处理。
• 不需要任何外部函数库(包括内存管理、文件/控制台的输入/输出和图形库等)。
• 它完全是作为一套头文件的集合而进行发布的。
上述这些优点使得CxxTest具有特别的可移植性和可用性。CxxTest遵循GNU LGPL许可证。
2. 特性
2.1 “TS_”系列宏
在用户的测试语句当中,可以使用下列不同的“断言”(assertions):
(1)宏TS_FAIL
宏TS_FAIL仅仅使测试失败,它的作用如同提供了出错信息的断言“assert(false)”。例如:
class SillySuite : public CxxTest::TestSuite {
public:
void testSomething( void )
{
TS_FAIL( "I don't know how to test this!" );
}
};
(2)宏TS_ASSERT
宏TS_ASSERT是基本、而功能非常强大的测试语句。它的工作原理如同宏“assert()”(我真的希望用户知道并能够使用这个宏!)。这方面的一个例子如下所示:
class TestFileLibrary : public CxxTest::TestSuite
{
public:
void testSquare( void )
{
MyFileLibrary::createEmptyFile("test.bin");
TS_ASSERT( access( "test.bin", 0 ) ==0 );
}
};
(3)宏TS_ASSERT_EQUALS
宏TS_ASSERT_EQUALS是第二个最为有用的测试语句。顾名思义,它被用来确认两个数值是相同的。一个例子如下所示:
class TestIntegerMathLibrary : public CxxTest::TestSuite
{
public:
void testSquare( void )
{
TS_ASSERT_EQUALS( square(-5), 25 );
}
};
(4)宏TS_ASSERT_DELTA
宏TS_ASSERT_DELTA的功能同宏TS_ASSERT_EQUALS的功能类似,它被用来在一个给定的偏差范围之内,确认两个数值是相等的。同时,它基本上是用于浮点数值。一个例子如下所示:
class TestFloatingPointMathLibrary : public CxxTest::TestSuite
{
public:
void testSquareRoot( void )
{
TS_ASSERT_DELTA( squareRoot(4.0), 2.0, 0.00001 );
}
};
(5)宏TS_ASSERT_DIFFERS
宏TS_ASSERT_DIFFERS的功能同宏TS_ASSERT_EQUALS的功能相反,它被用来确认两个数值是不相同的。一个例子如下所示:
class TestNumberGenerator : public CxxTest::TestSuite
{
public:
void testSquare( void )
{
int first =generateNumber();
int second =generateNumber();
TS_ASSERT_DIFFERS( first, second );
}
};
perl怎么下载(6)宏TS_ASSERT_LESS_THAN
宏TS_ASSERT_LESS_THAN断言,第一个操作数小于第二个操作数,如下所示:
class TestIncreaser : public CxxTest::TestSuite
{
public:
void testIncreaser( void )
{
TS_ASSERT_LESS_THAN( 23, findLargerNumber(23) );
}
};
(7)TS_ASSERT_THROWS/TS_ASSERT_THROWS_ANYTHING/TS_ASSERT_THROWS_NOTHING
这些断言被用来对出现异常的某些代码进行测试。当你想对程序抛出的异常类型进行确认时,可以使用宏TS_ASSERT_THROWS;而如果你仅仅是为了确认程序抛出了异常,则可以使用宏TS_ASSERT_THROWS_ANYTHING。正如你可能已经猜想到的那样,可以使用宏TS_ASSERT_THROWS_NOTHING来断言程序没有抛出异常。例子如下所示:
class TestTouchyFunctions : public CxxTest::TestSuite
{
public:
void testStandardThrower( void )
{
TS_ASSERT_THROWS_NOTHING( checkInput(1) );
TS_ASSERT_THROWS( checkInput(-11), std::runtime_error );
}
void testOtherThrower( void )
{
TS_ASSERT_THROWS_ANYTHING( otherThrower() );
}
};
2.2 “ETS_”系列宏
上述“TS_”系列宏将自动捕获测试的代码抛出的异常,并使得测试的条件不满足,从而造成失败,如同
你调用了TS_FAIL()一般。然而,有的时候,你或许想对测试的代码抛出的异常进行人为的捕获,这时,你就可以使用“ETS_”系列宏。
class TestInterestingThrower : public CxxTest::TestSuite
{
public:
void testInterestingThrower()
{
//通常的捕获异常的方式:当捕获到异常时,我们并不能对引发异常的源头进行检查;
TS_ASSERT_EQUALS( foo(2), 4 );
//更加精确的捕获异常的方式:
try {
ETS_ASSERT_EQUALS( foo(2), 4 );
} catch( const BadFoo &e ) {
TS_FAIL( e.bar() );
}
}
};
2.3 “TSM_”系列宏
有的时候,由ErrorPrinter生成的缺省的输出并不能够为你提供足够的信息(类这种情形经常是发生在当你把公共的测试功能移动到测试套件(Test Suite)的帮助函数当中的时候;这样,当一个断言失败时,而你并不知道断言失败的源头。
在下面的这个例子当中(它来自CxxTest发布软件包当中的文件“sample/MessageTest.h”),我们需要这
个方面的信息,以知道到底是哪一次对checkValue()的调用没有成功而引发了异常。
class MessageTest : public CxxTest::TestSuite
{
public:
void testValues()
{
checkValue( 0, "My hovercraft" );
checkValue( 1, "is full" );
checkValue( 2, "of eels" );
}
void checkValue( unsigned value, const char *message )
{
TSM_ASSERT( message, value );
TSM_ASSERT_EQUALS( message, value, value * value );
}
};
注意:如同所有通常的断言,“TSM_”系列宏有着它们对应的对于非异常攻击的(non-exception-safe)宏,即“ETSM_”系列宏。
2.4 测试套路(Test fixtures)
当你对同一个模块产生了几个不同的测试用例之后,你经常会发现,所有这些测试用例或多或少地开始于相同的代码,如创建对象、文件、输入等等。它们也可能有着相同的结束,即清理你在代码上遗留下的混乱(就是保护现场和恢复现场)。
这时,你可以通过重写虚函数TestSuite::setUp()以及TestSuite::tearDown(),把这些代码放置在相同的
地方。然后,在进行每一个测试之前,将调用setUp();而在结束每一个测试之后,将调用tearDown()。一个例子如下所示:
class TestFileOps : public CxxTest::TestSuite
{
public:
void setUp() { mkdir("playground"); }
void tearDown() { system( "rm -Rf playground"); }
void testCreateFile()
{
FileCreator fc( "playground" );
TS_ASSERT_EQUALS( access( "playground/test.bin", 0 ), 0 );
}
};
有关CxxTest的高级议题
本部分中所列的议题是更加倾向于技术层次上的;而且,除非你需要它们,否则,你只会觉得它们枯燥乏味。
1. 对用户自定义的数据类型的值进行等同性比较
你可能已经注意到了,宏TS_ASSERT_EQUALS只是对CxxTest内建的数据类型才起作用。这是因为,如果测试条件不能满足而引发异常时,为了打印出异常的消息,CxxTest需要一种方法把待比较的对象转换成为字符串。
如果你确实想把宏TS_ASSERT_EQUALS应用到用户自定义的数据类型上,你需要做下面一些工作。
首先,不要忘了在用户自定义的数据类型上实现运算符“等号”(==)!
1.1 数值特性(Value traits)
由于CxxTest试图独立于任何外部的函数库(包括标准函数库,因为标准函数库也并不总是可用的),在将任意的数据类型转换成为字符串时,CxxTest是通过数值特性(ValueTraits)的使用来实现的。
例如,为了把一个整数转换成为字符串,CxxTest执行下列一些操作:
·int i = value to convert(需要进行数据类型转换的整数);
·CxxTest::ValueTraits<int> converter(i);;
·string = temp.asString();;
CxxTest在头文件“cxxtest/ValueTraits.h”当中为int、char、dobule等基本的数据类型提供了预定义的数值特性(ValueTraits)。
1.2 定义新的数值特性
为新的数据类型定义新的数值特性是很容易的。一个例子可能如下所示:
class MyClass {
public:
//...
bool operator== ( const MyClass & ) const;
const char *converToString() const;
};
#ifdef CXXTEST_RUNNING //它由test runner来定义;
#include <cxxtest/ValueTraits.h>
namespace CxxTest {
class ValueTraits<MyClass> {
const MyClass &_m;
public:
ValueTraits( const MyClass &m ) : _m(m) {}
const char *asString() { return _m.convertToString(); }
};
};
#endif // CXXTEST_RUNNING
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论