外部依赖项:
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)
分析:
推迟的错误码和谓词匹配,测试通过
本文详细介绍了谷歌测试库gtest的使用,包括如何处理外部依赖、编写Main函数,重点讲解了断言的运用、事件机制(Test Fixtures)、参数化测试及死亡测试的实现,为单元测试提供全面的实践指导。

5829

被折叠的 条评论
为什么被折叠?



