英文:
is there a construct in catch2 to express a mapping of inputs vs. expected values?
问题
I have a set of inputs and their corresponding expected outputs for a function.
The test is currently written as follows:
TEST_CASE("test reverse_and_double")
{
struct { string input, string expected_output } tests[] = {
{ "abcd", "dcba" },
{ "hello", "olleh" },
//...
};
for(auto &t : tests) {
string output = my_reverse(t.input); // function under test
REQUIRE(output.size() == t.expected_output.size())
CHECK(std::equal(output.begin(), output.end(), t.expected_output.begin()));
//... many lines of CHECK & REQUIRE here...
}
}
Now, in theory, unit-tests should not have (complex) mechanisms in order to be readable. GENERATE()
is the way Catch offers in order to use the same CHECKs for different inputs. So, I tried it and I removed the for
loop:
TEST_CASE("test reverse_and_double")
{
struct { string input, string expected_output } t = GENERATE(
{ "abcd", "dcba" },
{ "hello", "olleh" },
//...
);
string output = my_reverse(t.input); // function under test
REQUIRE(output.size() == t.expected_output.size())
CHECK(std::equal(output.begin(), output.end(), t.expected_output.begin()));
//... many lines of CHECK & REQUIRE here...
}
However, there still is a 'mechanism' buried in the struct
of inputs vs expected outputs. Many people will have different ways of writing this. I suppose this is a common pattern in unit-tests. Does Catch offer a built-in construct to express such situations in a consistent way?
英文:
I have a set of inputs and their corresponding expected outputs for a function.
The test is currently written as follows:
TEST_CASE("test reverse_and_double")
{
struct { string input, string expected_output } tests[] = {
{ "abcd", "dcba" },
{ "hello", "olleh" },
//...
};
for(auto &t : tests) {
string output = my_reverse(t.input); // function under test
REQUIRE(output.size() == t.expected_output.size())
CHECK(std::equal(output.begin(), output.end(), t.expected_output.begin()));
//... many lines of CHECK & REQUIRE here...
}
}
Now, in theory, unit-tests should not have (complex) mechanisms in order to be readable.
GENERATE()
is the way Catch offers in order to use the same CHECKs for different inputs.
So, I tried it and I removed the for
loop:
TEST_CASE("test reverse_and_double")
{
struct { string input, string expected_output } t = GENERATE(
{ "abcd", "dcba" },
{ "hello", "olleh" },
//...
);
string output = my_reverse(t.input); // function under test
REQUIRE(output.size() == t.expected_output.size())
CHECK(std::equal(output.begin(), output.end(), t.expected_output.begin()));
//... many lines of CHECK & REQUIRE here...
}
}
However, there still is a 'mechanism' buried in the struct
of inputs vs expected outputs. Many people will have different ways of writing this.
I suppose this is a common pattern in unit-tests.
Does Catch offer a build-in construct to express such situations in a consistent way?
答案1
得分: 1
Yes it is possible, but documentation lacks off good examples, in this case you need feed table<...>
generator to GENERATE
macro:
std::string my_reverse(std::string_view s)
{
return {s.rbegin(), s.rend()};
}
TEST_CASE("test reverse_and_double")
{
auto [input, expected_output] = GENERATE(table<std::string, std::string>({
{ "abcd", "dcba" },
{ "hello", "olleh" },
}));
CAPTURE(input);
REQUIRE(my_reverse(input) == expected_output);
}
https://godbolt.org/z/GbrPxdbrb
I had problems understanding documentation and had to inspect unit test and other projects source code on github to fill gaps.
Note I used CAPTURE
so it is clear which argument was used when test fails.
英文:
Yes it is possible, but documentation lacks off good examples, in this case you need feed table<...>
generator to GENERATE
macro:
std::string my_reverse(std::string_view s)
{
return {s.rbegin(), s.rend()};
}
TEST_CASE("test reverse_and_double")
{
auto [input, expected_output] = GENERATE(table<std::string, std::string>({
{ "abcd", "dcba" },
{ "hello", "olleh" },
}));
CAPTURE(input);
REQUIRE(my_reverse(input) == expected_output);
}
https://godbolt.org/z/GbrPxdbrb
I had problems understanding documentation and had to inspect unit test and other projects source code on github to fill gaps.
Note I used CAPTURE
so it is clear which argument was used when test fails.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论