c++ catch2中是否有一个结构来表达输入值与期望值的Map?

vsmadaxz  于 2023-04-13  发布在  其他
关注(0)|答案(1)|浏览(98)

对于一个函数,我有一组输入和它们对应的预期输出
测试目前编写如下:

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...
    }
}

现在,从理论上讲,单元测试不应该有(复杂的)机制,以便可读。GENERATE()是Catch提供的方式,以便对不同的输入使用相同的CHECK。所以,我尝试了它,并删除了for循环:

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...
    }
}

然而,在输入与预期输出的struct中仍然隐藏着一种“机制”。许多人会有不同的书写方式。我想这是单元测试中的常见模式。Catch是否提供了一个内置结构来以一致的方式表达这种情况?

omhiaaxx

omhiaaxx1#

是的,这是可能的,但documentation缺乏好的例子,在这种情况下,你需要饲料table<...>生成器到GENERATE宏:

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
我在理解文档方面遇到了问题,不得不在github上检查单元测试和其他项目的源代码以填补空白。
注意我使用了CAPTURE,所以当测试失败时使用哪个参数是很清楚的。

相关问题