gtest 参数化
前言:
在测试用例中,我们时常需要传给被测函数不同的值,gtest为我们提供了简便的方法,可以使我们能够灵活的进行参数化测试。
步骤:
1.创建一个类,继承testing::TestWithParam<T>,T是你需要参数化的参数类型,比如参数类型为int
2. 使用新宏TEST_P替代TEST。在TEST_P宏里,可以使用GetParam()获取当前的参数的具体值。
3. 使用INSTANTIATE_TEST_CASE_P宏来输入测试参数。
参数解释和表格直接贴上某个大佬的解释:
第一个参数是测试案例的前缀,可以任意取。
第二个参数是测试案例的名称,需要和之前定义的参数化的类的名称相同。
第三个参数是可以理解为参数生成器,上面的例子使用test::Values表示使用括号内的参数。Google提供了一系列的参数生成的函数:
Range(begin, end[, step]) | 范围在begin~end之间,步长为step,不包括end |
Values(v1, v2, ..., vN) | v1,v2到vN的值 |
ValuesIn(container) and ValuesIn(begin, end) | 从一个C类型的数组或是STL容器,或是迭代器中取值 |
Bool() | 取false 和 true 两个值 |
Combine(g1, g2, ..., gN) |
这个比较强悍,它将g1,g2,...gN进行排列组合,g1,g2,...gN本身是一个参数生成器,每次分别从g1,g2,..gN中各取出一个值,组合成一个元组(Tuple)作为一个参数。 说明:这个功能只在提供了<tr1/tuple>头的系统中有效。gtest会自动去判断是否支持tr/tuple,如果你的系统确实支持,而gtest判断错误的话,你可以重新定义宏GTEST_HAS_TR1_TUPLE=1 |
示例:
示例1:最简单的Values()的使用。
1 /*********************************************** 2 3 Filename : test3.cpp 4 Author : 5 Description : 6 Create Data : 2018-10-21 03:15:54 7 Modfiy History : 2018-10-21 03:15:54 8 9 ***********************************************/ 10 11 #include <iostream> 12 13 #include <gtest/gtest.h> 14 15 using namespace std; 16 17 class myTest : public testing::TestWithParam<int> 18 { 19 20 }; 21 22 TEST_P(myTest, test0) 23 { 24 int num = GetParam(); 25 cout << num << endl; 26 } 27 28 INSTANTIATE_TEST_CASE_P(ttt, myTest, testing::Values(1, 2, 3, 4)); 29 30 int main(int argc, char *argv[]) 31 { 32 testing::InitGoogleTest(&argc, argv); 33 34 return RUN_ALL_TESTS(); 35 }
编译及结果:
示例2:Combine(g1, g2, ..., gN)的使用
1 /*********************************************** 2 3 Filename : test1.cpp 4 Author : 5 Description : 6 Create Data : 2018-10-21 02:40:25 7 Modfiy History : 2018-10-21 02:40:25 8 9 ***********************************************/ 10 11 #include <iostream> 12 #include <gtest/gtest.h> 13 14 using namespace std; 15 16 class funcTest : public testing::TestWithParam< tr1::tuple<int , int> > 17 { 18 protected: 19 virtual void SetUp() 20 { 21 // 如果此时参数是<1, 2> 22 // 那么 a = 1 23 // b = 2 24 a = tr1::get<0>(GetParam()); 25 b = tr1::get<1>(GetParam()); 26 } 27 virtual void TearDown() 28 { 29 30 } 31 int a; 32 int b; 33 }; 34 35 int func(int a, int b) 36 { 37 return a + b; 38 } 39 40 TEST_P(funcTest, test0) 41 { 42 cout << a << " + " << b <<" = " << func(a , b) << endl; 43 } 44 45 /*INSTANTIATE_TEST_CASE_P(MyFuncTest, 46 funcTest, 47 Combine(testing::Values(1, 2, 3), testing::Bool()));*/ 48 49 INSTANTIATE_TEST_CASE_P(MyFuncTest, 50 funcTest, 51 testing::Combine(testing::Values(1, 2, 3), testing::Values(1, 2))); 52 53 int main(int argc, char *argv[]) 54 { 55 testing::InitGoogleTest(&argc, argv); 56 57 return RUN_ALL_TESTS(); 58 }
编译及结果:
示例3:传参结构体
1 /*********************************************** 2 3 Filename : test2.cpp 4 Author : 5 Description : 6 Create Data : 2018-10-21 02:54:46 7 Modfiy History : 2018-10-21 02:54:46 8 9 ***********************************************/ 10 11 #include <iostream> 12 #include <gtest/gtest.h> 13 14 using namespace std; 15 16 using ::testing::TestWithParam; 17 using ::testing::Bool; 18 using ::testing::Values; 19 20 struct T 21 { 22 int a; 23 double b; 24 string c; 25 }; 26 27 class MyTest : public TestWithParam<struct T> 28 { 29 protected: 30 virtual void SetUp() 31 { 32 t1.a = GetParam().a; 33 t1.b = GetParam().b; 34 t1.c = GetParam().c; 35 } 36 virtual void TearDown() 37 { 38 39 } 40 41 struct T t1; 42 }; 43 44 TEST_P(MyTest, test0) 45 { 46 cout << t1.a<< " - " << t1.b << " - " << t1.c << endl; 47 } 48 49 INSTANTIATE_TEST_CASE_P(ttt1, MyTest, Values(T{1, 2.2 ,"cc"}, T{2, 3.3 ,"ee"})); 50 51 int main(int argc, char *argv[]) 52 { 53 testing::InitGoogleTest(&argc, argv); 54 55 return RUN_ALL_TESTS(); 56 }
编译及结果:
总结:
gtest的参数化功能真的是很方便,可以让我们以更少的代码,写出更强大的测试模块。