【问题标题】:Identifying the used base class in a type-parameterized Test using googletest使用 googletest 在类型参数化测试中识别使用的基类
【发布时间】:2019-04-10 14:05:52
【问题描述】:

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

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
  }
}

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

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

typeid(TypeParam).name()

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

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

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

【问题讨论】:

标签: c++ unit-testing googletest


【解决方案1】:

您可以使用一维整数0123、...标记base1&lt;1&gt;base1&lt;2&gt;base2&lt;1&gt;base2&lt;2&gt;、...遵循类模板TestsWrapper。 更具体地说,TestsWrapper&lt;...T&gt;::getIdx&lt;U&gt;() 返回 U 类型在 parameter pack ...T 中的位置。 例如,

  • TestsWrapper&lt;A,B,C,D,E&gt;::getIdx&lt;A&gt;()0
  • TestsWrapper&lt;A,B,C,D,E&gt;::getIdx&lt;B&gt;()1
  • TestsWrapper&lt;A,B,C,D,E&gt;::getIdx&lt;C&gt;()2

等等。 这使我们能够在编译时将测试类标识为TestsWrapper&lt;base1&lt;1&gt;, base1&lt;2&gt;, base2&lt;1&gt;, base2&lt;2&gt;&gt;::getIdx&lt;TypeParam&gt;()

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...>();
   }
};

该类模板用于类型化测试的使用示例如下。 这里idx是上面的整数标签0123,...并保存当前测试的类型。 您可以使用此标签来标识当前测试的类。 我已经检查过这种方法在我的 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>();
   ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-13
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多