一个简单的一个标题解决方案,用于C/C ++的单元测试。
只需在您的代码中#include "utest.h" !
当前支持的平台是Linux,MacOS和Windows。
当前支持的编译器是GCC,Clang,MSVC的CL.EXE和Clang-Cl.Exe。
它还可以与TCC一起使用,但有一个警告:TCC编译器的最新版本(0.9.27版)缺少UTEST工作的功能。确保使用用构造函数属性扩展程序修补的TCC。最近的Ubuntu和Debian Linux发行版将TCC运送到该补丁。如果您自己编译了TCC,请使用TRUNK版本,它将按预期工作。
utest.h支持一些命令行选项:
--help输出帮助消息--filter=<filter>将过滤测试用例(可用于重新运行一个特定的有害测试用例)。--list-tests将列出每行测试名称。输出名称可以传递给--filter 。--output=<output>将输出带有测试结果的Xunit XML文件(Jenkins,Travis-CI和Appveyor可以分析测试结果)。--enable-mixed-units将使每个测试输出能够包含混合单元(S/MS/US/NS)。--random-order[=<seed>]将随机化测试所在的顺序。如果未提供可选参数,则使用随机的启动种子。 UTEST是一个单个标头库,可在C和C ++中启用所有单元测试的乐趣。该库旨在提供类似于Google的Googletest Framework类似的输出:
[==========] Running 1 test cases.
[ RUN ] foo.bar
[ OK ] foo.bar (631ns)
[==========] 1 test cases ran.
[ PASSED ] 1 tests.
在一个C或C ++文件中,您必须调用Macro utest_main:
UTEST_MAIN ()这将调用utest.h,实例化所有测试柜并运行单元测试框架。
另外,如果您想编写自己的主体并致电utest.h,则可以在一个C或C ++文件调用中:
UTEST_STATE ();然后,当您准备打电话到UTEST时。H框架要做:
int main ( int argc , const char * const argv []) {
// do your own thing
return utest_main ( argc , argv );
}要定义要运行的测试用例,您可以执行以下操作;
#include "utest.h"
UTEST ( foo , bar ) {
ASSERT_TRUE ( 1 );
}UTEST宏带有两个参数 - 第一个是测试用例所属的集合,第二个是测试的名称。为了方便起见,这允许进行测试。
固定测试柜是一个可以在多个测试柜上共享的结构的结构。
struct MyTestFixture {
char c ;
int i ;
float f ;
};
UTEST_F_SETUP ( MyTestFixture ) {
utest_fixture -> c = 'a' ;
utest_fixture -> i = 42 ;
utest_fixture -> f = 3.14f ;
// we can even assert and expect in setup!
ASSERT_EQ ( 42 , utest_fixture -> i );
EXPECT_TRUE (true);
}
UTEST_F_TEARDOWN ( MyTestFixture ) {
// and also assert and expect in teardown!
ASSERT_EQ ( 13 , utest_fixture -> i );
}
UTEST_F ( MyTestFixture , a ) {
utest_fixture -> i = 13 ;
// teardown will succeed because i is 13...
}
UTEST_F ( MyTestFixture , b ) {
utest_fixture -> i = 83 ;
// teardown will fail because i is not 13!
}上面证明的一些事情要注意:
UTEST_F_SETUP和UTEST_F_TEARDOWN宏 - 即使它们在体内什么都不做。有时,您想反复使用相同的固定装置和测试柜,但可能会巧妙地更改一个变量。这是索引测试柜进来的地方。
struct MyTestIndexedFixture {
bool x ;
bool y ;
};
UTEST_I_SETUP ( MyTestIndexedFixture ) {
if ( utest_index < 30 ) {
utest_fixture -> x = utest_index & 1 ;
utest_fixture -> y = ( utest_index + 1 ) & 1 ;
}
}
UTEST_I_TEARDOWN ( MyTestIndexedFixture ) {
EXPECT_LE ( 0 , utest_index );
}
UTEST_I ( MyTestIndexedFixture , a , 2 ) {
ASSERT_TRUE ( utest_fixture -> x | utest_fixture -> y );
}
UTEST_I ( MyTestIndexedFixture , b , 42 ) {
// this will fail when the index is >= 30
ASSERT_TRUE ( utest_fixture -> x | utest_fixture -> y );
}笔记:
符合Googletest的内容,我们提供了每个错误检查条件的两个变体 - 断言和期望。如果断言失败,则测试案例将停止执行,并且UTEST.H将继续下一个要运行的测试案例。如果期望失败,将仍将执行测试案例的其余部分,从而进行进一步的检查。
我们目前提供以下宏位于UTEST中:
断言x评估为true(例如非零)。
UTEST ( foo , bar ) {
int i = 1 ;
ASSERT_TRUE ( i ); // pass!
ASSERT_TRUE ( 42 ); // pass!
ASSERT_TRUE ( 0 ); // fail!
}断言x评估为false(例如零)。
UTEST ( foo , bar ) {
int i = 0 ;
ASSERT_FALSE ( i ); // pass!
ASSERT_FALSE ( 1 ); // fail!
}断言x和y是相等的。
UTEST ( foo , bar ) {
int a = 42 ;
int b = 42 ;
ASSERT_EQ ( a , b ); // pass!
ASSERT_EQ ( a , 42 ); // pass!
ASSERT_EQ ( 42 , b ); // pass!
ASSERT_EQ ( 42 , 42 ); // pass!
ASSERT_EQ ( a , b + 1 ); // fail!
}断言X和Y不等。
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
ASSERT_NE ( a , b ); // pass!
ASSERT_NE ( a , 27 ); // pass!
ASSERT_NE ( 69 , b ); // pass!
ASSERT_NE ( 42 , 13 ); // pass!
ASSERT_NE ( a , 42 ); // fail!
}断言x小于y。
UTEST ( foo , bar ) {
int a = 13 ;
int b = 42 ;
ASSERT_LT ( a , b ); // pass!
ASSERT_LT ( a , 27 ); // pass!
ASSERT_LT ( 27 , b ); // pass!
ASSERT_LT ( 13 , 42 ); // pass!
ASSERT_LT ( b , a ); // fail!
}断言x小于或等于y。
UTEST ( foo , bar ) {
int a = 13 ;
int b = 42 ;
ASSERT_LE ( a , b ); // pass!
ASSERT_LE ( a , 27 ); // pass!
ASSERT_LE ( a , 13 ); // pass!
ASSERT_LE ( 27 , b ); // pass!
ASSERT_LE ( 42 , b ); // pass!
ASSERT_LE ( 13 , 13 ); // pass!
ASSERT_LE ( 13 , 42 ); // pass!
ASSERT_LE ( b , a ); // fail!
}断言x大于y。
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
ASSERT_GT ( a , b ); // pass!
ASSERT_GT ( a , 27 ); // pass!
ASSERT_GT ( 27 , b ); // pass!
ASSERT_GT ( 42 , 13 ); // pass!
ASSERT_GT ( b , a ); // fail!
}断言x大于或等于y。
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
ASSERT_GE ( a , b ); // pass!
ASSERT_GE ( a , 27 ); // pass!
ASSERT_GE ( a , 13 ); // pass!
ASSERT_GE ( 27 , b ); // pass!
ASSERT_GE ( 42 , b ); // pass!
ASSERT_GE ( 13 , 13 ); // pass!
ASSERT_GE ( 42 , 13 ); // pass!
ASSERT_GE ( b , a ); // fail!
}断言字符串x和y是相等的。
UTEST ( foo , bar ) {
char * a = "foo" ;
char * b = "bar" ;
ASSERT_STREQ ( a , a ); // pass!
ASSERT_STREQ ( b , b ); // pass!
ASSERT_STREQ ( a , b ); // fail!
}断言字符串X和Y不等。
UTEST ( foo , bar ) {
char * a = "foo" ;
char * b = "bar" ;
ASSERT_STRNE ( a , b ); // pass!
ASSERT_STRNE ( a , a ); // fail!
}断言字符串x和y等于字符串x的长度。
UTEST ( foo , bar ) {
char * a = "foobar" ;
char * b = "foo" ;
ASSERT_STRNEQ ( a , a ); // pass!
ASSERT_STRNEQ ( b , b ); // pass!
ASSERT_STRNEQ ( a , b ); // pass!
}断言字符串x和y不等于字符串x的长度。
UTEST ( foo , bar ) {
char * a = "foobar" ;
char * b = "bar" ;
ASSERT_STRNNE ( a , b ); // pass!
ASSERT_STRNNE ( a , a ); // fail!
}断言浮点值x和y彼此之间的距离范围内。
UTEST ( foo , bar ) {
float a = 42.0f ;
float b = 42.01f ;
ASSERT_NEAR ( a , b , 0.01f ); // pass!
ASSERT_NEAR ( a , b , 0.001f ); // fail!
}断言执行代码X时将抛出异常_type。
void foo ( int bar) {
if (bar == 1 )
throw std::range_error;
}
UTEST (foo, bar) {
ASSERT_EXCEPTION ( foo ( 1 ), std::range_error); // pass!
ASSERT_EXCEPTION ( foo ( 2 ), std::range_error); // fail!
ASSERT_EXCEPTION ( foo ( 1 ), std:: exception ); // fail!
}期望x评估为true(即非零)。
UTEST ( foo , bar ) {
int i = 1 ;
EXPECT_TRUE ( i ); // pass!
EXPECT_TRUE ( 42 ); // pass!
EXPECT_TRUE ( 0 ); // fail!
}期望X评估为false(IE零)。
UTEST ( foo , bar ) {
int i = 0 ;
EXPECT_FALSE ( i ); // pass!
EXPECT_FALSE ( 1 ); // fail!
}期望x和y相等。
UTEST ( foo , bar ) {
int a = 42 ;
int b = 42 ;
EXPECT_EQ ( a , b ); // pass!
EXPECT_EQ ( a , 42 ); // pass!
EXPECT_EQ ( 42 , b ); // pass!
EXPECT_EQ ( 42 , 42 ); // pass!
EXPECT_EQ ( a , b + 1 ); // fail!
}期望x和y不等。
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
EXPECT_NE ( a , b ); // pass!
EXPECT_NE ( a , 27 ); // pass!
EXPECT_NE ( 69 , b ); // pass!
EXPECT_NE ( 42 , 13 ); // pass!
EXPECT_NE ( a , 42 ); // fail!
}期望x小于y。
UTEST ( foo , bar ) {
int a = 13 ;
int b = 42 ;
EXPECT_LT ( a , b ); // pass!
EXPECT_LT ( a , 27 ); // pass!
EXPECT_LT ( 27 , b ); // pass!
EXPECT_LT ( 13 , 42 ); // pass!
EXPECT_LT ( b , a ); // fail!
}期望x小于或等于y。
UTEST ( foo , bar ) {
int a = 13 ;
int b = 42 ;
EXPECT_LE ( a , b ); // pass!
EXPECT_LE ( a , 27 ); // pass!
EXPECT_LE ( a , 13 ); // pass!
EXPECT_LE ( 27 , b ); // pass!
EXPECT_LE ( 42 , b ); // pass!
EXPECT_LE ( 13 , 13 ); // pass!
EXPECT_LE ( 13 , 42 ); // pass!
EXPECT_LE ( b , a ); // fail!
}期望x大于y。
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
EXPECT_GT ( a , b ); // pass!
EXPECT_GT ( a , 27 ); // pass!
EXPECT_GT ( 27 , b ); // pass!
EXPECT_GT ( 42 , 13 ); // pass!
EXPECT_GT ( b , a ); // fail!
}期望x大于或等于y。
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
EXPECT_GE ( a , b ); // pass!
EXPECT_GE ( a , 27 ); // pass!
EXPECT_GE ( a , 13 ); // pass!
EXPECT_GE ( 27 , b ); // pass!
EXPECT_GE ( 42 , b ); // pass!
EXPECT_GE ( 13 , 13 ); // pass!
EXPECT_GE ( 42 , 13 ); // pass!
EXPECT_GE ( b , a ); // fail!
}期望字符串x和y相等。
UTEST ( foo , bar ) {
char * a = "foo" ;
char * b = "bar" ;
EXPECT_STREQ ( a , a ); // pass!
EXPECT_STREQ ( b , b ); // pass!
EXPECT_STREQ ( a , b ); // fail!
}期望字符串X和Y不等。
UTEST ( foo , bar ) {
char * a = "foo" ;
char * b = "bar" ;
EXPECT_STRNE ( a , b ); // pass!
EXPECT_STRNE ( a , a ); // fail!
}期望字符串x和y等于字符串x的长度。
UTEST ( foo , bar ) {
char * a = "foobar" ;
char * b = "foo" ;
EXPECT_STRNEQ ( a , a ); // pass!
EXPECT_STRNEQ ( b , b ); // pass!
EXPECT_STRNEQ ( a , b ); // pass!
}期望字符串x和y不等于字符串x的长度。
UTEST ( foo , bar ) {
char * a = "foobar" ;
char * b = "bar" ;
EXPECT_STRNNE ( a , b ); // pass!
EXPECT_STRNNE ( a , a ); // fail!
}期望浮点值x和y在彼此之间的Epsilon距离之内。
UTEST ( foo , bar ) {
float a = 42.0f ;
float b = 42.01f ;
EXPECT_NEAR ( a , b , 0.01f ); // pass!
EXPECT_NEAR ( a , b , 0.001f ); // fail!
}预计执行代码X时会抛出异常。
void foo ( int bar) {
if (bar == 1 )
throw std::range_error;
}
UTEST (foo, bar) {
EXPECT_EXCEPTION ( foo ( 1 ), std::range_error); // pass!
EXPECT_EXCEPTION ( foo ( 2 ), std::range_error); // fail!
EXPECT_EXCEPTION ( foo ( 1 ), std:: exception ); // fail!
}预计执行代码X时,except_type将会带有消息except_message。
void foo ( int bar) {
if (bar == 1 )
throw std::range_error ( " bad bar " );
}
UTEST (foo, bar) {
EXPECT_EXCEPTION_WITH_MESSAGE ( foo ( 1 ), std::range_error, " bad bar " ); // pass!
EXPECT_EXCEPTION_WITH_MESSAGE ( foo ( 2 ), std::range_error, " bad bar2 " ); // fail!
EXPECT_EXCEPTION_WITH_MESSAGE ( foo ( 1 ), std:: exception , " bad bar " ); // fail!
}此宏使您可以将测试用例标记为被跳过的 - 例如。不得执行测试案例。测试将在执行宏观时停止运行,将msg报告为跳过的原因,并将测试标记为“跳过” 。这些将在执行结束前报告,然后跳过测试用例不会导致该过程以非零代码退出。
UTEST ( foo , bar ) {
UTEST_SKIP ( "Need to implement this test!" );
}此外,为了在故障测试中使用自定义消息的可能性,所有宏都可以与称为“ _msg”的后缀一起使用,该后缀接收一个额外的参数,该参数是带有自定义消息的字符串,以便在失败时打印。
例如:
UTEST ( foo , bar ) {
int i = 1 ;
EXPECT_TRUE_MSG ( i , "custom message" ); // pass!
EXPECT_TRUE_MSG ( 42 , "custom message" ); // pass!
EXPECT_TRUE_MSG ( 0 , "custom message" ); // fail! (with the following output)
} test.cpp:42: Failure
Expected : true
Actual : false
Message : custom message
[ FAILED ] foo.bar (8086ns)
该库支持在任何内置整数,浮点或指针类型上宣称。
这是发布到公共领域的免费且无限制的软件。
任何人都可以免费复制,修改,发布,使用,编译,出售或分发此软件,无论是源代码表单还是作为二进制编译的二进制,出于任何目的,商业或非商业目的以及任何方式。
在承认版权法的司法管辖区中,该软件的作者或作者将软件中的任何和所有版权兴趣献给公共领域。我们将这种奉献精神献给了整个公众的利益,并损害了我们的继承人和继承人。我们打算将这种奉献精神奉献给根据版权法的永久性和未来权利的永久性行为。
该软件是“原样”提供的,没有任何形式的明示或暗示保证,包括但不限于适销性,特定目的的适用性和非侵权的保证。在任何情况下,作者均不应对任何索赔,损害赔偿或其他责任责任,无论是在合同,侵权或其他方面的诉讼中,与软件,使用或软件中的使用或其他交易有关。
有关更多信息,请参阅http://unlicense.org/