Как запустить параметризованные тесты со значениями элементов фикстуры в Google Test (gtest)?

То, чего я хочу достичь, — это параматеризованный тест TEST_P(MyFixtureClass, DoStuff), с помощью которого я могу проверить разные значения. Хотя указанные значения не должны быть постоянными, как те, которые обычно передаются INSTANTIATE_TEST_CASE_P, Более того, я хотел бы использовать значения в каком-то другом классе приборов — в идеале.

Кажется, что-то там не так, что охватывает использование полей вместо статических значений при создании параметризованных тестов. официальная документация кажется, не покрыть это тоже — к сожалению.


Но чтобы избежать введения проблемы XY в этом вопросе, вот эквивалентный псевдокод:

Параметризованный крепеж, MyFixture:

struct MyFixture : OtherFixture, ::testing::WithParamInterface<float>
{
float a;

void SetUp() override
{
a = GetParam();
}
};

OtherFixture будет выглядеть так:

struct OtherFixture : testing::Test
{
float a;
float b;
float c;

void SetUp() override
{
a = CalculateSomeFloat();
b = CalculateSomeFloat();
c = CalculateSomeFloat();
}
};

Тестовый пример будет что-то вроде:

// This here is the key aspect.
// Basically, I do not want to write a bunch of tests for a, b and c.
// Rather, I'd just test all 3 with this one.
TEST_P(MyFixture, DoStuff)
{
...bunch of tests
}

И, наконец, мы бы создали экземпляры параметризованных тестов:

INSTANTIATE_TEST_CASE_P(MyFloatTesting, MyFixture, ::testing::Values(
OtherFixture::a, OtherFixture::b, OtherFixture::c
));

Очевидно, что OtherFixture::a неуместно, но оно иллюстрирует, где я хотел бы сослаться на поле внутри унаследованного класса приборов (или любого другого класса приборов в этом отношении).


Так есть ли способ достичь этого с помощью gtest? Мне не обязательно использовать параметризованные тесты. Мне просто не нужно писать одни и те же тесты для разных объектов.

Любые предложения очень ценятся!

3

Решение

Я думаю, что вам нужно использовать ::testing::Combine.

И изменить параметры из float в std::tuple<float, float OtherFixture::*>,

using OtherFixtureMemberAndValue = std::tuple<float, float OtherFixture::*>;

struct MyFixture : OtherFixture, ::testing::WithParamInterface<OtherFixtureMemberAndValue>
{
float a = std::get<0>(GetParam());
auto& memberToTest()
{
return this->*std::get<1>(GetParam());
}};

Для определения набора параметров используйте этот подход:

const auto membersToTest = testing::Values(
&OtherFixture::a,
&OtherFixture::b,
&OtherFixture::c
);

const auto floatValuesToTest = testing::Values(
2.1,
3.2
//  ...
);

INSTANTIATE_TEST_CASE_P(AllMembers,
MyFixture,
testing::Combine(floatValuesToTest, membersToTest));

Затем вы можете написать свои тесты в отношении членов OtherFixture:

TEST_P(MyFixture, test)
{
ASSERT_EQ(a, memberToTest());
}

Я бы тоже советовал что ты написал PrintTo за float OtherFixture::*:

void PrintTo(float OtherFixture::*member, std::ostream* os)
{
if (member == &OtherFixture::a)
*os << "&OtherFixture::a";
else if (member == &OtherFixture::b)
*os << "&OtherFixture::b";
else if (member == &OtherFixture::c)
*os << "&OtherFixture::c";
else
*os << "&OtherFixture::? = " << member;

}

Таким образом, вы получите хорошее сообщение в случае неудачи:

[FAILED] AllMembers / MyFixture.test / 5, где GetParam () = (3.2,
&OtherFixture :: гр)

по сравнению с неприятным, бессмысленным сообщением без PrintTo:

[FAILED] AllMembers / MyFixture.test / 5, где GetParam () = (3.2,
4-байтовый объект <10-00 00-00>)

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]