То, чего я хочу достичь, — это параматеризованный тест 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? Мне не обязательно использовать параметризованные тесты. Мне просто не нужно писать одни и те же тесты для разных объектов.
Любые предложения очень ценятся!
Я думаю, что вам нужно использовать ::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>)
Других решений пока нет …