Gtest

发布时间:2026/11/6 4:50:39
Gtest

一、初始Gtest和框架搭建

1.4 Demo

intFoo(inta,intb){if(a==0||b==0){throw"don't do that";}intc=a%b;if(c==0)returnb;returnFoo(b,c);}
#include<gtest/gtest.h>TEST(FooTest,HandleNoneZeroInput){EXPECT_EQ(2,Foo(4,10));EXPECT_EQ(6,Foo(30,18));}

二、断言

2.1 前言

GTest中,断言的宏可以理解为分为两类,一类是ASSERT系列,一类是EXPECT系列。一个直观的解释就是:

  • ASSERT_*系列的断言,当检查点失败时,退出当前函数(注意:并非退出当前testcase)
  • EXPECT_*系列的断言,当检查点失败时,继续往下执行

2.2 自定义提示信息实例

未使用自定义提示

for(inti=0;i<x.size();++i){EXPECT_EQ(x[i],y[i]);}#结果:无法看出出错时到底是循环到哪里了/* g:\myproject\c++\gtestdemo\gtestdemo\gtestdemo.cpp(25): error: Value of: y[i] Actual: 4 Expected: x[i] Which is: 3 */

使用<<操作符自定义提示输出

for(inti=0;i<x.size();++i){EXPECT_EQ(x[i],y[i])<<"Vectors x and y differ at index "<<i;}/* 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 */

2.3 bool值类型检查

ASSERTEXPECT
检查失败退出函数检查失败继续往下执行
ASSERT_TRUE(condition);EXPECT_TRUE(condition);
ASSERT_FALSE(condition);EXPECT_FALSE(condition);

2.4 数值型检查

Fatal assertionNonfatal assertionVerifies
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

2.5 字符串检查

Fatal assertionNonfatal assertionVerifies
ASSERT_STREQ(expected_str,actual_str);EXPECT_STREQ(expected_str,actual_str);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);same content, ignoring case
ASSERT_STRCASENE(str1,str2);EXPECT_STRCASENE(str1,str2);different content, ignoring case

2.6 显示返回成功或失败

  1. 直接返回成功SUCCEED()
  2. 返回失败
Fatal assertionNonfatal assertion
FAIL();ADD_FAILURE();
TEST(ExplicitTest,Demo){ADD_FAILURE()<<"Sorry";// None Fatal Asserton,继续往下执行。//FAIL() << "Sorry!"; // Fatal Assertion,不继续往下执行该案例。SUCCEED();}

2.7 异常检查

Fatal assertionNonfatal assertionVerifies
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
intFoo(inta,intb){if(a==0||b==0){throw"don't do that";}intc=a%b;if(c==0)returnb;returnFoo(b,c);}TEST(FooTest,HandleZeroInput){EXPECT_ANY_THROW(Foo(10,0));EXPECT_THROW(Foo(0,5),char*);}

2.8 Predicate Assertions

是对ASSERT_TRUE和EXPECT_TRUE的改进,使其不仅判断TRUE和FALSE,而且能显示其他信息,比如输入的参数内容。
如下分别是一个输入参数和两个输入参数的使用。

Fatal assertionNonfatal assertionVerifies
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
boolMutuallyPrime(intm,intn){returnFoo(m,n)>1;}TEST(PredicateAssertionTest,Demo){intm=5,n=6;EXPECT_PRED2(MutuallyPrime,m,n);}/* 当失败时,返回错误信息: error: MutuallyPrime(m, n) evaluates to false, where m evaluates to 5 n evaluates to 6 */

2.9 浮点型检查

Fatal assertionNonfatal assertionVerifies
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

2.9.1 相近数比较

Fatal assertionNonfatal assertionVerifies
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

2.10 Windows HRESULT 检查

Fatal assertionNonfatal assertionVerifies
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));

2.11 类型检查

template<typenameT>classFooType{public:voidBar(){testing::StaticAssertTypeEq<int,T>();}};TEST(TypeAssertionTest,Demo){FooType<bool>fooType;fooType.Bar();}

三、事件机制

3.1 前言

事件:在案例执行之前或之后做的一些操作。
共有三个粒度:

  1. 全局级别的。在所有案例的第一个执行前,和所有案例最后一个执行后。
  2. TestSuite级别的。在某一批案例中的第一个案例前,最后一个案例执行后。
  3. TsetCase级别的。每个TestCase前后。
    特别需要注意区分粒度。
粒度解释
全局有50个testcase,SetUp在第1个testcase前执行,TearDown在第50个testcase后执行。
TestSuite有50个testcase,其中针对这一个TestSuite的testcase是第20-30个,则此SetUpTestCase在第20个testcase前执行,TearDownTestCase在第30个testcase后执行。
TestCaseSetUp使用此事件的每一个testcase前执行一次,TearDown在 使用此事件的每一个testcase后执行一次

3.2 全局级别

要实现全局级别的事件:

  1. 写一个类,继承testing::Environment类,实现SetUp和TearDown
  2. 在main函数中通过testing::AddGlobalTestEnvironment把事件挂进来。

我们有50个testcase,SetUp在第1个testcase前执行,TearDown在第50个testcase后执行。

3.2.1 实现SetUP和TearDown
classFooEnvironment:publictesting::Environment{public:virtualvoidSetUp(){std::cout<<"Foo FooEnvironment SetUP"<<std::endl;}virtualvoidTearDown(){std::cout<<"Foo FooEnvironment TearDown"<<std::endl;}public:intdwRet;};
3.2.2 挂载事件
int_tmain(intargc,_TCHAR*argv[]){testing::AddGlobalTestEnvironment(newFooEnvironment);testing::InitGoogleTest(&argc,argv);returnRUN_ALL_TESTS();}

3.3 TestSuite事件

要实现TestSuite级别(某一批)的事件:

  1. 写一个类,继承testing::Test类,实现静态方法SetUpTestCase和TearDownTestCase

我们有50个testcase,其中针对这一个TestSuite的testcase是第20-30个,则此SetUpTestCase在第20个testcase前执行,TearDownTestCase在第30个testcase后执行。

classFooTest:publictesting::Test{protected:staticvoidSetUpTestCase(){shared_resource_=new;}staticvoidTearDownTestCase(){deleteshared_resource_;shared_resource_=NULL;}staticT*shared_resource_;};

在编写测试案例时,我们需要使用TEST_F这个宏,第一个参数必须是我们上面类的名字,代表一个TestSuite

TEST_F(FooTest,Given_When_Then){// you can refer to shared_resource here}TEST_F(FooTest,Given_When_Then){// you can refer to shared_resource here}
3.4 TestCase事件

TestCase是在每个testcase执行前执行,也在每个testcase执行后执行。

classTEST_Command_Parse:publictesting::Test{public:CoreInfo*coreInfo;2.在main函数中通过t`esting::AddGlobalTestEnvironment`把事件挂进来。public:virtualvoidSetUp(){coreInfo=InitCoreNetwork();}virtualvoidTearDown(){CloseCoreNetwork(coreInfo);}};#include"gtest/gtest.h"GTEST_API_intmain(intargc,char**argv){testing::InitGoogleTest(&argc,argv);returnRUN_ALL_TESTS();}

四、死亡测试

//暂缺

五、运行参数

5.1 命令行参数

gtest同样能够处理命令行参数,因为在main函数中我们把命令行参数交给了gtest。

int_tmain(intargc,_TCHAR*argv[]){testing::InitGoogleTest(&argc,argv);returnRUN_ALL_TESTS();}

由gtest来搞定命令行问题,这样就可以使用命令行参数来使得gtest达到我们想要的效果,比如:

参数作用
–gtest_list_tests使用这个参数时,将不会执行里面的测试案例,而是输出一个案例的列表。

5.2 代码中指定FLAG

gtest提供了不止一种设置运行参数的方法:

  • 命令行参数
  • 代码中指定FLAG
  • 系统环境变量

  • 优先级为:命令行参数 > 代码中指定FLAG > 系统环境变量
  • 代码指定FLAG:testing::GTEST_FLAG(output) = "xml:"

代码中指定FLAG,可以使用testing::GTEST_FLAG这个宏来设置,推荐将这句放在InitGoogleTest之前,这样就可以使得对于同样的参数,命令行参数优先级高于代码指定。

int_tmain(intargc,_TCHAR*argv[]){testing::GTEST_FLAG(output)="xml:";testing::InitGoogleTest(&argc,argv);returnRUN_ALL_TESTS();}

5.3 列表

命令行参数说明
–gtest_list_tests
–gtest_filter
–gtest_also_run_disabled_tests
–gtest_repeat=[COUNT]
–gtest_color=(yes\no\auto)
–gtest_print_time
–gtest_output=xml[:DIRECTORY_PATH|:FILE_PATH]
异常处理异常处理
–gtest_break_on_failure调试模式下,当案例失败时停止,方便调试
–gtest_throw_on_failure
–gtest_catch_exceptions

5.4 总结

本篇主要介绍了gtest案例执行时提供的一些参数的使用方法,这些参数都非常有用。在实际编写gtest测试案例时肯定会需要用到的时候。至少我现在比较常用的就是:

  1. –gtest_filter
    //运行所有测试./my_test--gtest_filter=*//只运行 MathOperations 套件下的所有测试./my_test--gtest_filter=MathOperations.*
  2. –gtest_output=xml[:DIRECTORY_PATH|:FILE_PATH]
  3. –gtest_catch_exceptions
    最后再总结一下我使用过程中遇到的几个问题:
  4. 同时使用–gtest_filter和–gtest_output=xml:时,在xml测试报告中能否只包含过滤后的测试案例的信息。
  5. 有时,我在代码中设置 testing::GTEST_FLAG(catch_exceptions) = 1和我在命令行中使用–gtest_catch_exceptions结果稍有不同,在代码中设置FLAG方式有时候捕捉不了某些异常,但是通过命令行参数的方式一般都不会有问题。这是我曾经遇到过的一个问题,最后我的处理办法是既在代码中设置FLAG,又在命令行参数中传入–gtest_catch_exceptions。不知道是gtest在catch_exceptions方面不够稳定,还是我自己测试案例的问题。