1、简介
  在设计测试案例时,经常需要考虑给被测函数传入不同的值的情况。按照之前的通用方法,需要多次调用同一个函数,这种做法很不方便,效率也不好。
如:
TEST(IsPrimeTest, HandleTrueReturn)
{
      EXPECT_TRUE(IsPrime(3));
      EXPECT_TRUE(IsPrime(5));
      EXPECT_TRUE(IsPrime(11));
      EXPECT_TRUE(IsPrime(23));
      EXPECT_TRUE(IsPrime(17));
  ......
}
这种方法就是1个测试案例,有5个检查点。而且传入再多的值也无法保证函数正确。IsPrime函数在gtest的example1.cc中。因此Google使用参数化的方法解决这种问题。
2、参数化
2.1 告知gtest需要使用的参数类型
  必须添加一个类,继承testing::TestWithParam<T>,其中T就是你需要参数化的参数类型。如:参数化int型的参数(放在头文件中)
class myTest : public testing::TestWithParam<int>
{
};
2.2 告知gtest拿到参数后执行的操作当前的参数的具体值
如:
TEST_P(myTest, test0)
{
	  int num = GetParam();
	  EXPECT_EQ(num,num)<<"GetParam:"<<GetParam()<<",num:"<<num;
}
此处TEST_P宏中的第一个参数和头文件中定义的参数化的类名相同。
2.3 告知gtest要测试的参数范围
使用INSTANTIATE_TEST_CASE_P宏,如:
  INSTANTIATE_TEST_CASE_P(isParamTestInt, myTest, testing::Values(1, 2, 3, 4));
该宏的参数解析:
  isParamTestInt:测试案例的前缀,随意取即可
  myTest:测试案例名称,要和定义的参数化的类的名称相同
  testing::Values(1, 2, 3, 4):参数生成器
该宏放在与TEST_P宏(2.2)相同的文件。
2.4 参数生成函数
  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)作为一个参数。
					  注意:Combine只在提供了<tr1/tuple>头的系统中有效。gtest会自动去判断是否支持tr/tuple,如果你的系统确实支持,而gtest判断错误的话,你可以重新定义宏GTEST_HAS_TR1_TUPLE=1。
2.5 参数化后的输出
  4 tests from isParamTestInt/myTest
  [ RUN      ] isParamTestInt/myTest.test0/0
  [       OK ] isParamTestInt/myTest.test0/0 (0 ms)
  [ RUN      ] isParamTestInt/myTest.test0/1
  [       OK ] isParamTestInt/myTest.test0/1 (0 ms)
  [ RUN      ] isParamTestInt/myTest.test0/2
  [       OK ] isParamTestInt/myTest.test0/2 (0 ms)
  [ RUN      ] isParamTestInt/myTest.test0/3
  [       OK ] isParamTestInt/myTest.test0/3 (0 ms)
  [----------] 4 tests from isParamTestInt/myTest (4 ms total)
格式:INSTANTIATE_TEST_CASE_P的第一个参数 / TEST_P第一个参数 . TEST_P第二个参数 / testing::Values中参数的序号,从0开始
3、类型参数化
gtest还提供了应付各种不同类型的数据时的方案,以及参数化类型的方案。
3.1 定义1个模板类,继承testing::Test
template <typename T> class FooTest : public testing::Test {
  public:
	    ...
	    typedef std::list<T> List;
	    static T shared_;
	    T value_;
};
3.2 定义需要测试到的具体数据类型
定义需要测试char,int和unsigned int :
  typedef testing::Types<char, int, unsigned int> MyTypes;
  TYPED_TEST_CASE(FooTest, MyTypes);
3.3 使用TYPED_TEST宏完成测试案例,在声明模版的数据类型时,使用TypeParam
TYPED_TEST(FooTest, DoesBlah) {
	  // 在测试中,引用特殊名称TypeParam以获取类型参数。
	  // 由于我们在一个派生类模板中,所以C++要求我们通过“this”访问FooTest的成员 
	  TypeParam n = this->value_;
	  // 访问fixture的静态成员, 添加'TestFixture::'前缀
	  n += TestFixture::shared_;
	  // 需要引用fixture中的typedefs, 添加'typename TestFixture::'前缀
	  typename TestFixture::List values;
	  values.push_back(n);
}
该示例需要事先知道类型的列表。
  gtest还提供一种更加灵活的类型参数化的方式,允许你在完成测试的逻辑代码之后再去考虑需要参数化的类型列表,并且还可以重复的使用这个类型列表。
3.4 官方的另一种方案
3.4.1 定义模板类
template <typename T>
class FooTest : public testing::Test {
};
TYPED_TEST_CASE_P(FooTest);
与3.1 一致,先定义模板类。
3.4.2 使用TYPED_TEST_P宏完成测试案例
TYPED_TEST_P(FooTest, DoesBlah) {
    // 测试中,参考TypeParam以获取类型参数
    TypeParam n = 0;
}
TYPED_TEST_P(FooTest, HasPropertyA) { }
3.4.3 使用REGISTER_TYPED_TEST_CASE_P宏
  REGISTER_TYPED_TEST_CASE_P(FooTest, DoesBlah, HasPropertyA);
第一个参数是testcase的名称,后面的参数是test的名称
3.4.4 指定需要的类型列表
  typedef testing::Types<char, int, unsigned int> MyTypes;
  INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
这种方案相比之前的方案提供更加好的灵活度,当然,框架越灵活,复杂度也会随之增加。
来源:https://www.cnblogs.com/Sheenagh/p/12215339.html