I want to test a template function on a range of values and a range of types. So something like
template <class T>
void foo(Bar<T>&);
But the issue is I can't get the google test's value parametrised tests to work with template test suite. Most of my tests currently look like this:
TYPED_TEST(FooTest, foo) {
for (int repeats = 0 ...) { // don't want this
Bar<TypeParam> bar;
for (... i < repeats ...)
foo(bar);
EXPECT_EQ(bar, /*...*/);
}
}
So I am looking for a way to get rid of that first for loop and pass repeats as a const parameter instead. And just in case you are wondering here is the real test file. Although its not entirely this way right now because I am refactoring this code.
I have tried this so far:
using NumericTypes = ::testing::Types<uint8_t /*...*/ >;
template <class T>
class FooTest
: public ::testing::TestWithParam<const int> { };
TYPED_TEST_SUITE(FooTest,
NumericTypes,
TestingTypenames);
INSTANTIATE_TEST_SUITE_P(SomeFooTest,
FooTest,
testing::Range(0,3));
The error I am getting:
foo.cpp: error: template argument 1 is invalid
16 | INSTANTIATE_TEST_SUITE_P(SomeFooTest,
| ^~~~~~~~~~~~~~~~~~~~~~~~
So these type parametrized tests are making wonders for me its just the for loops that are bothering me. And in the new tests I am writing there would be 3 layers of for loops because I am testing nested lists and they will behave differently if they are nested.
If you can, it is much easier either to pass your values as template arguments or to pass your types as values.
An example with values as template arguments:
#include <variant>
#include <gtest/gtest.h>
template<typename T, T value>
struct param1 {
static T get(){ return value; }
};
template <typename >
class example1
: public ::testing::Test { };
using params = ::testing::Types<
param1<uint8_t, 0>,
param1<uint8_t, 1>,
param1<uint16_t, 0>
>;
TYPED_TEST_SUITE(example1, params);
TYPED_TEST(example1, test) {
ASSERT_TRUE(TypeParam::get() < 2);
}
And with types as values:
using param2 = std::variant<uint8_t, uint16_t>;
class example2 : public ::testing::TestWithParam<param2> {};
INSTANTIATE_TEST_SUITE_P(foo, example2, testing::Values<param2>(
uint8_t(0),
uint8_t(1),
uint16_t(0)
));
TEST_P(example2, test) {
std::visit([&](auto value){
ASSERT_TRUE(value < 2);
}, GetParam());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With