gtest使用说明

本文详细介绍了谷歌测试库gtest的使用,包括如何处理外部依赖、编写Main函数,重点讲解了断言的运用、事件机制(Test Fixtures)、参数化测试及死亡测试的实现,为单元测试提供全面的实践指导。

外部依赖项:

liggtest.a  libgtest_main.a  相关头文件

Main函数写法参考:

int main(int argc,char* argv[])
{ 
    //testing::GTEST_FLAG(output) = "xml:"; //生成xml结果文件
    testing::InitGoogleTest(&argc,argv); //初始化
    if( RUN_ALL_TESTS())                     //跑单元测试
    return 0;
}

1.断言的使用

1)ASSERT_* 断言

	ASSERT_*系列断言,当检查点失败时,退出当前函数
	
	例如:有如下两个测试用例:

	TEST(unit,assert_t_1)
	{
		ASSERT_EQ(4,Add(1,2));
		ASSERT_EQ(3,Add(1,2));
	}


	TEST(unit,assert_t_2)
	{
		ASSERT_EQ(4,Add(1,3));
	}

	输出结果:

	main startinit[==========] Running 2 tests from 1 test suite.
	[----------] Global test environment set-up.
	[----------] 2 tests from unit
	[ RUN      ] unit.assert_t_1
	unittest.cpp:5: Failure
	Expected equality of these values:
	  4
	  Add(1,2)
		Which is: 3
	[  FAILED  ] unit.assert_t_1 (0 ms)
	[ RUN      ] unit.assert_t_2
	[       OK ] unit.assert_t_2 (0 ms)
	[----------] 2 tests from unit (0 ms total)

	[----------] Global test environment tear-down
	[==========] 2 tests from 1 test suite ran. (0 ms total)
	[  PASSED  ] 1 test.
	[  FAILED  ] 1 test, listed below:
	[  FAILED  ] unit.assert_t_1


	分析:

	上面实际上只跑了两个用例,当 assert_t_1 测试第一个测试点测试失败时,整个函数都退出,转向执行第二个函数。
 
2)EXPECT_* 断言

    EXPECT_* 断言当检查点失败时,会继续往下执行
	
	例如:如下俩个测试用例:
	
	TEST(unitqxcept,except_t_1)
	{
		std::cout<<"first point\n";
		EXPECT_EQ(4,Add(1,2));
		std::cout<<"second point\n";
		EXPECT_EQ(3,Add(1,2));
	}

	TEST(unitqxcept,except_t_2)
	{
		std::cout<<"third point\n";
		EXPECT_EQ(4,Add(1,3));
	}
	
	测试结果:
	
	main startinitNote: Google Test filter = unitqxcept.*
	[==========] Running 2 tests from 1 test suite.
	[----------] Global test environment set-up.
	[----------] 2 tests from unitqxcept
	[ RUN      ] unitqxcept.except_t_1
	first point
	unittest.cpp:19: Failure
	Expected equality of these values:
	  4
	  Add(1,2)
		Which is: 3
	second point
	[  FAILED  ] unitqxcept.except_t_1 (0 ms)
	[ RUN      ] unitqxcept.except_t_2
	third point
	[       OK ] unitqxcept.except_t_2 (0 ms)
	[----------] 2 tests from unitqxcept (0 ms total)

	[----------] Global test environment tear-down
	[==========] 2 tests from 1 test suite ran. (1 ms total)
	[  PASSED  ] 1 test.
	[  FAILED  ] 1 test, listed below:
	[  FAILED  ] unitqxcept.except_t_1
	
	分析:在第一个测试点测试失败后,函数没有退出,而是继续第二个测试点

总结:

常见的断言有:

布尔值检查: *_TRUE *_FALSE

数值型检查: *_EQ 等于  *_NE 不等于  小于 *_LT  *_LE 小于等于 *_GT 大于 *_GE  大于等于

字符串检查: *_STREQ 等于  *_STRNQ 不等于   *_STRCASEEQ 忽略大小写,两个子串相等  *_STRCASEEQ 忽略大小写,两个子串不相等

2.事件机制(Test Fixures)

gtest的事件机制,方便在gtest的测试用例之前或之后做一些操作。

    1)全局事件
    
	全局事件用于在所有案例的前后执行某种操作
	
	测试用例:
	
	class TestEnvironment : public testing::Environment
	{

	public:

		virtual void SetUp()
		{
			std::cout<<"test environment setup"<<std::endl;
		}

		virtual void TearDown()
		{
			 std::cout<<"test environment TearDown"<<std::endl;
		}
	};
	
	
	定义一个继承自testing::Environment的类,在main函数中添加语句
	
	testing::AddGlobalTestEnvironment(new TestEnvironment);
	
    测试结果:
	[----------] Global test environment set-up.
	test environment setup
	[----------] 1 test from unitassert
	[ RUN      ] unitassert.assert_t_1
	unittest.cpp:6: Failure
	Expected equality of these values:
	  4
	  Add(1,2)
		Which is: 3
	[  FAILED  ] unitassert.assert_t_1 (0 ms)
	[----------] 1 test from unitassert (0 ms total)

	[----------] Global test environment tear-down
	test environment TearDown
    
	分析:
	
	由结果看出,在测试用例执行前,执行了 SetUp()打印操作,
	在用例执行完成以后,执行TearDown()打印操作。
	
	2)TestSuite事件
	
	在某一个案例第一个案例前,最后一个案例后
	
	测试用例:
	
	class TestSuit : public testing::Test
	{
	protected:

		static void SetUpTestCase()
		{
			std::cout<<"TestSuit setup"<<std::endl;
		}

		static void TearDownTestCase()
		{
			 std::cout<<"TestSuit TearDown"<<std::endl;
		}
	};
	
	TEST_F(TestSuit,except_t_1)
	{
		EXPECT_EQ(3,Add(1,2));
	}
	
	注意,这里使用了TEST_F宏,宏的第一个参数是类的名字
	
	部分结果:
	
	[ RUN      ] unitqxcept.except_t_2
	third point
	[       OK ] unitqxcept.except_t_2 (0 ms)
	[----------] 2 tests from unitqxcept (0 ms total)

	[----------] 1 test from TestSuit
	TestSuit setup
	[ RUN      ] TestSuit.except_t_1
	[       OK ] TestSuit.except_t_1 (0 ms)
	TestSuit TearDown

    分析:
	
	如上述结果所示,TestSuit的SetUp只在TestSuit.except_t_1之前执行
	TestSuit TearDown的TearDown只在TestSuit.except_t_1之后执行。
	

3) TestCase事件与TestSuit基本相同,不再赘述

3.参数化

有些被测试函数需要传入多个不同的参数,为了避免书写重复代码,可以使用值参数化

1)值参数化

    测试用例:
	
	class IsPrimeParamTest : public::testing::TestWithParam<int>
	{

	};
	
	bool IsPrime(int n)
	{
		if(n<=1)return false;
		if(n%2==0)return n==2;
		for(int i =3;;i+=2)
		{
			if(i>n/i)break;
			if(n%2 ==0)return false;
		}
		return true;
	}
	
	INSTANTIATE_TEST_CASE_P(TrueReturn,IsPrimeParamTest,testing::Values(3,5,11,23,17)); //设定参数范围
	TEST_P(IsPrimeParamTest,HandleTrueReturn)
	{
		int n = GetParam();
		EXPECT_TRUE(IsPrime(n));
	}

    测试结果:
    

    [----------] 1 test from TestSuit (0 ms total)
	[----------] 5 tests from TrueReturn/IsPrimeParamTest
	[ RUN      ] TrueReturn/IsPrimeParamTest.HandleTrueReturn/0
	[       OK ] TrueReturn/IsPrimeParamTest.HandleTrueReturn/0 (0 ms)
	[ RUN      ] TrueReturn/IsPrimeParamTest.HandleTrueReturn/1
	[       OK ] TrueReturn/IsPrimeParamTest.HandleTrueReturn/1 (0 ms)
	[ RUN      ] TrueReturn/IsPrimeParamTest.HandleTrueReturn/2
	[       OK ] TrueReturn/IsPrimeParamTest.HandleTrueReturn/2 (0 ms)
	[ RUN      ] TrueReturn/IsPrimeParamTest.HandleTrueReturn/3
	[       OK ] TrueReturn/IsPrimeParamTest.HandleTrueReturn/3 (0 ms)
	[ RUN      ] TrueReturn/IsPrimeParamTest.HandleTrueReturn/4
	[       OK ] TrueReturn/IsPrimeParamTest.HandleTrueReturn/4 (0 ms)
	[----------] 5 tests from TrueReturn/IsPrimeParamTest (0 ms total)


    分析:
	
	如上述结果所示,TEST_P(IsPrimeParamTest,HandleTrueReturn)总共跑了5次测试用例
	
总结:
    
	参数生成器函数:
	
	Range(begin,end[,step]),范围在begin-end之间,步长为step,不包括end
	
	Values(v1,v2,....,vN) v1,v2到vN的值
	
	ValuesIn(container)and ValuesIn(begin,end) 从一个数组或容器里面取值
	
	Bool()  取false和true两个值
	
    Combine(g1,g2,....,gN) 从g1到gN取出数个值组成元组tuple (不太明白)
	
	
	
2)类型参数化

4.死亡测试

gtest的死亡测试用于在安全的环境下执行奔溃的测试案例

1) *_DEATH 用例因给定的错误而崩溃

    测试用例:
	
	void Foo()
	{
		int *pInt = 0;
		*pInt = 42;
	}

	TEST(FooDeathTest,Demo)
	{
		EXPECT_DEATH(Foo(),"");
	}

    测试结果:
	
	[==========] Running 1 test from 1 test suite.
	[----------] Global test environment set-up.
	[----------] 1 test from FooDeathTest
	[ RUN      ] FooDeathTest.Demo
	[       OK ] FooDeathTest.Demo (56 ms)
	[----------] 1 test from FooDeathTest (56 ms total)

	[----------] Global test environment tear-down
	[==========] 1 test from 1 test suite ran. (56 ms total)
	[  PASSED  ] 1 test.
    分析:
	
	Foo()触发了一个错误,测试通过
	
2)*_EXIT 

	用例因为错误退出,错误码与谓词匹配
	
	测试用例:
	
	TEST(ExitDeathTest,Demo)
	{
		 EXPECT_EXIT(_exit(1),testing::ExitedWithCode(1),"");
	}
    
    测试结果:
	
	[----------] 1 test from ExitDeathTest
	[ RUN      ] ExitDeathTest.Demo
	[       OK ] ExitDeathTest.Demo (18 ms)
	[----------] 1 test from ExitDeathTest (18 ms total)
     
	分析:
	
	推迟的错误码和谓词匹配,测试通过
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值