使用 googletest 在类型参数化测试中识别使用的基数 class

Identifying the used base class in a type-parameterized Test using googletest

正在翻新物理模拟,我正在尝试为要使用类型参数化测试替换的函数编写单元测试。基本设置如下所示:

using MyTypes = ::testing::Types<base1<1>, base1<2>, base2<1>, base2<2>>;
TYPED_TEST_CASE(tests, MyTypes);
TYPED_TEST(tests, testname){
  auto obj = clname(TypeParam);
  auto parameters = generate_values(TypeParam);      
  for( auto& p : parameters ){
    // Test if obj.func(p) equals the saved values
  }
}

由于基础 classes 和生成值的数量很大,我想将当前(假定正确)版本的输出写入文件并将新版本的输出与这些进行比较值。函数 (func) 根据 TypeParam 的不同而变化,因此我还需要以某种形式保存使用的基数 class。

但是,我不知道如何识别使用的基数 class:一种解决方案是保存并比较 typeid,如保存

typeid(TypeParam).name()

连同结果,但有人告诉我,这个值可以在机器之间改变,因此作为一个值没有用处。我试图在 MyTypes 中找到相应的条目,即为

保存 i
std::is_same<MyTypes[i],TypeParam>::value

是对的,但对任何i来说似乎都不是这样。有没有什么好的方法可以通过类型参数化测试来做到这一点?还是我需要完全使用其他东西?

您可以用一维整数标记 base1<1>base1<2>base2<1>base2<2>、... 01 , 2, 3, ... 使用以下 class 模板 TestsWrapper。 更具体地说,TestsWrapper<...T>::getIdx<U>() returns 类型 Uparameter pack ...T 中的位置。 例如,

  • TestsWrapper<A,B,C,D,E>::getIdx<A>()0
  • TestsWrapper<A,B,C,D,E>::getIdx<B>()1
  • TestsWrapper<A,B,C,D,E>::getIdx<C>()2,

等等。 这使我们能够在编译时将测试的 class 识别为 TestsWrapper<base1<1>, base1<2>, base2<1>, base2<2>>::getIdx<TypeParam>()

Live DEMO

template<class ...T>
class TestsWrapper
{
   template<class U>
   static constexpr std::size_t getIdx_impl()
   {
       return 0;
   }

   template<class U, class T0, class ...Ts>
   static constexpr std::size_t getIdx_impl()
   {
       return std::is_same<U, T0>::value ? 0 : (getIdx_impl<U, Ts...>() + 1);
   }

public:
   using Types = ::testing::Types<T...>;

   template<class U>
   static constexpr std::size_t getIdx()
   {
       return getIdx_impl<U, T...>();
   }
};

此class模板用于类型测试的用法示例如下。 这里idx就是上面的整数标签0123、……保存当前测试的是哪种类型。 您可以使用此标签来标识当前测试的 class。 我已经检查过这种方法在我的 Windows 环境中运行良好:

using TWrapper = TestsWrapper<base1<1>, base1<2>, base2<1>, base2<2>>;

template <typename T>
class test : public ::testing::Test {};

TYPED_TEST_CASE(test, TWrapper::Types);

TYPED_TEST(test, testname)
{
   constexpr auto idx = TWrapper::getIdx<TypeParam>();
   ...
}