【转】玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - 断言

转载 2011年05月21日 14:20:00

原文地址:http://www.cnblogs.com/coderzh/archive/2009/04/06/1430364.html

一、前言

这篇文章主要总结gtest中的所有断言相关的宏。 gtest中,断言的宏可以理解为分为两类,一类是ASSERT系列,一类是EXPECT系列。一个直观的解释就是:

1. ASSERT_* 系列的断言,当检查点失败时,退出当前函数(注意:并非退出当前案例)。

2. EXPECT_* 系列的断言,当检查点失败时,继续往下执行。

二、示例

//  int型比较,预期值:3,实际值:Add(1, 2) 
EXPECT_EQ( 3 , Add( 1  2 ))
//  

假如你的Add(1, 2) 结果为4的话,会在结果中输出:

g:/myproject/c ++ /gtestdemo/gtestdemo/gtestdemo.cpp( 16 ): error: Value of: Add( 1  2 )
  Actual: 
4 
Expected:
 3

如果是将结果输出到xml里的话,将输出:(关于将结果输出为xml,见:http://www.cnblogs.com/coderzh/archive/2009/04/10/1432789.html )

< testcase  name ="Demo"  status ="run"  time ="0"  classname ="AddTest" > 
      
 < failure  message ="Value of: Add(1, 2)   Actual: 4 Expected: 3"  type ="" > <![CDATA[ g:/myproject/c++/gtestdemo/gtestdemo/gtestdemo.cpp:16
Value of: Add(1, 2)
  Actual: 4
Expected: 3
 ]]> </ failure > 
</ testcase >

如果你对自动输出的出错信息不满意的话,你还可以通过操作符<<将一些自定义的信息输出,通常,这对于调试或是对一些检查点的补充说明来说,非常有用!

下面举个例子:

如果不使用<<操作符自定义输出的话:

for  ( int  i  =   0 ; i  <  x.size();  ++ i) 
{
    EXPECT_EQ(x[i], y[i])
 ;
}


看到的结果将是这样的,你根本不知道出错时 i 等于几:

g:/myproject/c ++ /gtestdemo/gtestdemo/gtestdemo.cpp( 25 ): error: Value of: y[i]
  Actual: 
 4 
Expected: x[i]
Which 
 is  3

如果使用<<操作符将一些重要信息输出的话:

for  ( int  i  =   0 ; i  <  x.size();  ++ i)
{
    EXPECT_EQ(x[i], y[i]) 
 <<   " Vectors x and y differ at index  "   <<  i;
}

从输出结果中就可以定位到在 i = 2 时出现了错误。这样的输出结果看起来更加有用,容易理解: 

g:/myproject/c ++ /gtestdemo/gtestdemo/gtestdemo.cpp( 25 ): error: Value of: y[i]
  Actual: 
 4 
Expected: x[i]
Which 
 is  3 
Vectors x and y differ at index 
 2

三、布尔值检查

Fatal assertion Nonfatal assertion Verifies
ASSERT_TRUE( condition ) ; EXPECT_TRUE( condition ) ; condition is true
ASSERT_FALSE( condition ) ; EXPECT_FALSE( condition ) ; condition is false

四、数值型数据检查

Fatal assertion Nonfatal assertion Verifies
ASSERT_EQ( expected actual ); EXPECT_EQ( expected actual ); expected == actual
ASSERT_NE( val1 val2 ); EXPECT_NE( val1 val2 ); val1 != val2
ASSERT_LT( val1 val2 ); EXPECT_LT( val1 val2 ); val1 < val2
ASSERT_LE( val1 val2 ); EXPECT_LE( val1 val2 ); val1 <= val2
ASSERT_GT( val1 val2 ); EXPECT_GT( val1 val2 ); val1 > val2
ASSERT_GE( val1 val2 ); EXPECT_GE( val1 val2 ); val1 >= val2

五、字符串检查 

Fatal assertion Nonfatal assertion Verifies
ASSERT_STREQ( expected_str actual_str ); EXPECT_STREQ( expected_str actual_str ); the two C strings have the same content
ASSERT_STRNE( str1 str2 ); EXPECT_STRNE( str1 str2 ); the two C strings have different content
ASSERT_STRCASEEQ( expected_str actual_str ); EXPECT_STRCASEEQ( expected_str actual_str ); the two C strings have the same content, ignoring case
ASSERT_STRCASENE( str1 str2 ); EXPECT_STRCASENE( str1 str2 ); the two C strings have different content, ignoring case

*STREQ*和*STRNE*同时支持类型的,*STRCASEEQ*和*STRCASENE*却只接收char*,估计是不常用吧。下面是几个例子:

TEST(StringCmpTest, Demo)
{
    
 char *  pszCoderZh  =   " CoderZh " ;
    wchar_t
 *  wszCoderZh  =  L " CoderZh " ;
    std::
 string  strCoderZh  =   " CoderZh " ;
    std::wstring wstrCoderZh 
 =  L " CoderZh " ;

    EXPECT_STREQ(
 " CoderZh " , pszCoderZh);
    EXPECT_STREQ(L
 " CoderZh " , wszCoderZh);

    EXPECT_STRNE(
 " CnBlogs " , pszCoderZh);
    EXPECT_STRNE(L
 " CnBlogs " , wszCoderZh);

    EXPECT_STRCASEEQ(
 " coderzh " , pszCoderZh);
    
 // EXPECT_STRCASEEQ(L"coderzh", wszCoderZh);    不支持 

    EXPECT_STREQ(
 " CoderZh " , strCoderZh.c_str());
    EXPECT_STREQ(L
 " CoderZh " , wstrCoderZh.c_str());
}

六、显示返回成功或失败

直接返回成功:SUCCEED();

返回失败:

Fatal assertion Nonfatal assertion
FAIL(); ADD_FAILURE();
TEST(ExplicitTest, Demo)
{
    ADD_FAILURE() 
 <<   " Sorry "  //  None Fatal Asserton,继续往下执行。

    
 // FAIL();  //  Fatal Assertion,不往下执行该案例。 

    SUCCEED();
}

七、异常检查

Fatal assertion Nonfatal assertion Verifies
ASSERT_THROW( statement , exception_type ); EXPECT_THROW( statement , exception_type ); statement throws an exception of the given type
ASSERT_ANY_THROW( statement ); EXPECT_ANY_THROW( statement ); statement throws an exception of any type
ASSERT_NO_THROW( statement ); EXPECT_NO_THROW( statement ); statement doesn't throw any exception

例如:

int  Foo( int  a,  int  b)
{
    
 if  (a  ==   0   ||  b  ==   0 )
    {
        
 throw   " don't do that " ;
    }
    
 int  c  =  a  %  b;
    
 if  (c  ==   0 )
        
 return  b;
    
 return  Foo(b, c);
}

TEST(FooTest, HandleZeroInput)
{
    EXPECT_ANY_THROW(Foo(
 10  0 ));
    EXPECT_THROW(Foo(
 0  5 ),  char * );
}

八、Predicate Assertions

在使用EXPECT_TRUE或ASSERT_TRUE时,有时希望能够输出更加详细的信息,比如检查一个函数的返回值TRUE还是FALSE时,希望能够输出传入的参数是什么,以便失败后好跟踪。因此提供了如下的断言:

Fatal assertion Nonfatal assertion Verifies
ASSERT_PRED1( pred1, val1 ); EXPECT_PRED1( pred1, val1 ); pred1(val1) returns true
ASSERT_PRED2( pred2, val1, val2 ); EXPECT_PRED2( pred2, val1, val2 ); pred2(val1, val2) returns true
... ... ...

Google人说了,他们只提供<=5个参数的,如果需要测试更多的参数,直接告诉他们。下面看看这个东西怎么用。

bool  MutuallyPrime( int  m,  int  n)
{
    
 return  Foo(m , n)  >   1 ;
}

TEST(PredicateAssertionTest, Demo)
{
    
 int  m  =   5 , n  =   6 ;
    EXPECT_PRED2(MutuallyPrime, m, n);
}

当失败时,返回错误信息:

error: MutuallyPrime(m, n) evaluates to false, where
m evaluates to 5
n evaluates to 6

如果对这样的输出不满意的话,还可以自定义输出格式,通过如下:

Fatal assertion Nonfatal assertion Verifies
ASSERT_PRED_FORMAT1( pred_format1, val1 );` EXPECT_PRED_FORMAT1( pred_format1, val1 ); pred_format1(val1) is successful
ASSERT_PRED_FORMAT2( pred_format2, val1, val2 ); EXPECT_PRED_FORMAT2( pred_format2, val1, val2 ); pred_format2(val1, val2) is successful
... ...

用法示例:

testing::AssertionResult AssertFoo( const   char *  m_expr,  const   char *  n_expr,  const   char *  k_expr,  int  m,  int  n,  int  k) {
    
 if  (Foo(m, n)  ==  k)
        
 return  testing::AssertionSuccess();
    testing::Message msg;
    msg 
 <<  m_expr  <<   "  和  "   <<  n_expr  <<   "  的最大公约数应该是: "   <<  Foo(m, n)  <<   "  而不是: "   <<  k_expr;
    
 return  testing::AssertionFailure(msg);
}

TEST(AssertFooTest, HandleFail)
{
    EXPECT_PRED_FORMAT3(AssertFoo, 
 3  6  2 );
}

失败时,输出信息:

error: 3 和 6 的最大公约数应该是:3 而不是:2

是不是更温馨呢,呵呵。

九、浮点型检查

Fatal assertion Nonfatal assertion Verifies
ASSERT_FLOAT_EQ( expected, actual ); EXPECT_FLOAT_EQ( expected, actual ); the two float values are almost equal
ASSERT_DOUBLE_EQ( expected, actual ); EXPECT_DOUBLE_EQ( expected, actual ); the two double values are almost equal

对相近的两个数比较:

Fatal assertion Nonfatal assertion Verifies
ASSERT_NEAR( val1, val2, abs_error ); EXPECT_NEAR (val1, val2, abs_error ); the difference between val1 and val2 doesn't exceed the given absolute error

同时,还可以使用:

EXPECT_PRED_FORMAT2(testing::FloatLE, val1, val2);
EXPECT_PRED_FORMAT2(testing::DoubleLE, val1, val2);

十、Windows HRESULT assertions

Fatal assertion Nonfatal assertion Verifies
ASSERT_HRESULT_SUCCEEDED( expression ); EXPECT_HRESULT_SUCCEEDED( expression ); expression is a success HRESULT
ASSERT_HRESULT_FAILED( expression ); EXPECT_HRESULT_FAILED( expression ); expression is a failure HRESULT

例如:

CComPtr shell;
ASSERT_HRESULT_SUCCEEDED(shell.CoCreateInstance(L
 " Shell.Application " ));
CComVariant empty;
ASSERT_HRESULT_SUCCEEDED(shell
 -> ShellExecute(CComBSTR(url), empty, empty, empty, empty));

十一、类型检查

类型检查失败时,直接导致代码编不过,难得用处就在这?看下面的例子:

template  < typename T >   class  FooType {
public :
    
 void  Bar() { testing::StaticAssertTypeEq < int , T > (); }
};

TEST(TypeAssertionTest, Demo)
{
    FooType
 < bool >  fooType;
    fooType.Bar();
}

十二、总结

 本篇将常用的断言都介绍了一遍,内容比较多,有些还是很有用的。要真的到写案例的时候,也行只是一两种是最常用的,现在时知道有这么多种选择,以后才方便查询。

 

Google C++单元测试框架(Gtest)系列教程之一——入门

引言 本文将先介绍单元测试的相关概念,然后引入Google的开源C++单元测试框架Gtest,最后通过编译、运行Gtest自带的一个测试样例,介绍如何在Unix/Linux下使用Gtest。 ...
  • u010229420
  • u010229420
  • 2016年06月29日 10:30
  • 1736

Google C++单元测试框架(Gtest)系列教程之四——参数化

本文转自http://www.cnblogs.com/bangerlee/archive/2011/10/08/2199701.html 引言 在上一篇文章中,我们学习了如何使用Gte...
  • tanningzhong
  • tanningzhong
  • 2014年11月21日 13:53
  • 477

google test 轻松编写C++单元测试

简介: googletest 与 googlemock 是 Google 公司于 2008 年发布的两套用于单元测试的应用框架,本文将向读者介绍如何应用这两套应用框架轻松编写 C++ 单元测试代码。...
  • peng825223208
  • peng825223208
  • 2016年05月12日 11:09
  • 2698

跨平台C++单元测试框架GTest -- Linux下试用

转自:http://graybull.is-programmer.com/posts/37871.html GTest是Google开发的跨平台而且开源的C++单元测试框架,很好很强大。首先...
  • u010492096
  • u010492096
  • 2013年12月04日 09:19
  • 981

玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - 断言

一、前言这篇文章主要总结gtest中的所有断言相关的宏。 gtest中,断言的宏可以理解为分为两类,一类是ASSERT系列,一类是EXPECT系列。一个直观的解释就是:1. ASSERT_* 系列的断...
  • scarin
  • scarin
  • 2013年12月20日 16:56
  • 469

玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - 断言

【转自】http://www.cnblogs.com/coderzh/archive/2009/04/06/1430364.html 一、前言 这篇文章主要总结gtest中...
  • xth6314
  • xth6314
  • 2014年03月07日 22:38
  • 459

玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - 断言

一、前言 这篇文章主要总结gtest中的所有断言相关的宏。 gtest中,断言的宏可以理解为分为两类,一类是ASSERT系列,一类是EXPECT系列。一个直观的解释就是: 1. ASSERT_...
  • Andeewu
  • Andeewu
  • 2013年12月16日 14:55
  • 400

玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - 断言

一、前言 这篇文章主要总结gtest中的所有断言相关的宏。 gtest中,断言的宏可以理解为分为两类,一类是ASSERT系列,一类是EXPECT系列。一个直观的解释就是: 1. ASS...
  • liujiayu2
  • liujiayu2
  • 2016年02月22日 17:11
  • 253

玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - 断言

原文地址:http://www.cnblogs.com/coderzh/archive/2009/04/06/1430364.html 一、前言 这篇文章主要总结gtest中的所有...
  • xiaogugood
  • xiaogugood
  • 2013年11月05日 08:45
  • 565

玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - 断言

一、前言 这篇文章主要总结gtest中的所有断言相关的宏。 gtest中,断言的宏可以理解为分为两类,一类是ASSERT系列,一类是EXPECT系列。一个直观的解释就是: 1. ASS...
  • shitsnail
  • shitsnail
  • 2017年06月07日 14:12
  • 326
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【转】玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - 断言
举报原因:
原因补充:

(最多只允许输入30个字)