Type-Parameterized Tests with two types. template <typename T, typename P> class FooTest : public ::testing::Test { }

2,131 views
Skip to first unread message

Adam

unread,
Apr 16, 2018, 4:12:42 PM4/16/18
to Google C++ Testing Framework
I love gtest! Very cool.

The one thing that would make my testing a lot easier is if I could specify multiple types like below:
template <typename T, typename P>
class FooTest : public ::testing::Test {
 
...
};

Is this possible some how?


Samuel Benzaquen

unread,
Apr 16, 2018, 4:26:19 PM4/16/18
to ada...@gmail.com, Google C++ Testing Framework
You can make your T be a std::tuple<> and have it have any number of elements in it.
 


--

---
You received this message because you are subscribed to the Google Groups "Google C++ Testing Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googletestframe...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Adam

unread,
Apr 17, 2018, 8:51:48 AM4/17/18
to Google C++ Testing Framework
Thanks for the quick reply! I'll be honest, I'm an embedded c programmer trying to use gtest to test a library that will work on various types.

The eventual goal is to use this for testing an open source filter library written in c with testing in c++.
I need to use Type-Parameterized Tests to allow new filters to be added and tested easily.

Here's a better example of what I'm trying to do:

extern "C" {
  typedef struct RedFilter8  { int8_t  number; } RedFilter8;
  typedef struct RedFilter16 { int16_t number; } RedFilter16;

  typedef struct BlueFilter8  { int8_t  number; } BlueFilter8;
  typedef struct BlueFilter16 { int16_t number; } BlueFilter16;
}

template <typename FilterType, typename PrimitiveType>
class FilterTestSuite : public testing::Test { };
TYPED_TEST_CASE_P(FilterTestSuite);

TYPED_TEST_P(FilterTestSuite, first_test) {
    FilterType filter;
    filter.number = helper<PrimitiveType>(); //setup stuff based on PrimitiveType
    //tests...
}

REGISTER_TYPED_TEST_CASE_P(FilterTestSuite, first_test);

typedef Types<std::tuple<RedFilter8, int8_t>, std::tuple<RedFilter16, int16_t>> RedTypes;
INSTANTIATE_TYPED_TEST_CASE_P(RedTests, FilterTestSuite, RedTypes);

typedef Types<std::tuple<BlueFilter8, int8_t>, std::tuple<BlueFilter16, int16_t>> BlueTypes;
INSTANTIATE_TYPED_TEST_CASE_P(RedTests, FilterTestSuite, BlueTypes);

I've tried various ways of using/declaring the tuple types, but haven't had any success.

Any advice?

Thanks again!

 

Adam

unread,
Apr 17, 2018, 10:54:08 AM4/17/18
to Google C++ Testing Framework
My apologies. There was a typo at the very last line. It should have said `BlueTests` instead of `RedTests`. The full corrected version is below:

extern "C" {
 
typedef struct RedFilter8  { int8_t  number; } RedFilter8;
 
typedef struct RedFilter16 { int16_t number; } RedFilter16;
 
 
typedef struct BlueFilter8  { int8_t  number; } BlueFilter8;
 
typedef struct BlueFilter16 { int16_t number; } BlueFilter16;
}
 
template <typename FilterType, typename PrimitiveType>
class FilterTestSuite : public testing::Test { };
TYPED_TEST_CASE_P(FilterTestSuite);
 
TYPED_TEST_P(FilterTestSuite, first_test) {
 
FilterType filter;
  filter
.number = helper<PrimitiveType>(); //setup stuff based on PrimitiveType
 
//tests...
}
 
REGISTER_TYPED_TEST_CASE_P(FilterTestSuite, first_test);
 
typedef Types<std::tuple<RedFilter8, int8_t>, std::tuple<RedFilter16, int16_t>> RedTypes;
INSTANTIATE_TYPED_TEST_CASE_P(RedTests, FilterTestSuite, RedTypes);
 
typedef Types<std::tuple<BlueFilter8, int8_t>, std::tuple<BlueFilter16, int16_t>> BlueTypes;
INSTANTIATE_TYPED_TEST_CASE_P(BlueTests, FilterTestSuite, BlueTypes);


Samuel Benzaquen

unread,
Apr 18, 2018, 12:54:45 PM4/18/18
to Adam Fraser-Kruck, Google C++ Testing Framework
On Tue, Apr 17, 2018 at 10:54 AM Adam <ada...@gmail.com> wrote:
My apologies. There was a typo at the very last line. It should have said `BlueTests` instead of `RedTests`. The full corrected version is below:

extern "C" {
 
typedef struct RedFilter8  { int8_t  number; } RedFilter8;
 
typedef struct RedFilter16 { int16_t number; } RedFilter16;
 
 
typedef struct BlueFilter8  { int8_t  number; } BlueFilter8;
 
typedef struct BlueFilter16 { int16_t number; } BlueFilter16;
}
 
template <typename FilterType, typename PrimitiveType>
class FilterTestSuite : public testing::Test { };

Your fixture is getting a single type, which happens to be a tuple.
So you can do something like:

template <typename Tuple>
class FilterTestSuite : public testing::Test { };

TYPED_TEST_P(FilterTestSuite, first_test) {
  using FilterType = typename std::tuple_element<0, TypeParam>::type;
  using PrimitiveType = typename std::tuple_element<1, TypeParam>::type;
  FilterType filter;
  filter.number = helper<PrimitiveType>(); //setup stuff based on PrimitiveType
  //tests...
}

TYPED_TEST_CASE_P(FilterTestSuite);
 
TYPED_TEST_P(FilterTestSuite, first_test) {
 
FilterType filter;
  filter
.number = helper<PrimitiveType>(); //setup stuff based on PrimitiveType
 
//tests...
}
 
REGISTER_TYPED_TEST_CASE_P(FilterTestSuite, first_test);
 
typedef Types<std::tuple<RedFilter8, int8_t>, std::tuple<RedFilter16, int16_t>> RedTypes;
INSTANTIATE_TYPED_TEST_CASE_P(RedTests, FilterTestSuite, RedTypes);
 
typedef Types<std::tuple<BlueFilter8, int8_t>, std::tuple<BlueFilter16, int16_t>> BlueTypes;
INSTANTIATE_TYPED_TEST_CASE_P(BlueTests, FilterTestSuite, BlueTypes);


Adam Fraser-Kruck

unread,
Apr 18, 2018, 9:17:20 PM4/18/18
to Samuel Benzaquen, Google C++ Testing Framework
This works perfectly! Thanks a million :)

To unsubscribe from this group and stop receiving emails from it, send an email to googletestframework+unsub...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages