使用Catch框架测试C ++模板类 [英] Test C++ template class using Catch framework

查看:175
本文介绍了使用Catch框架测试C ++模板类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在寻找一个好的方法来使用Catch测试一个模板类。我有几乎可以工作的东西:

I'm looking for a good way to use Catch to test a templated class. I have something that almost works:

#define RUN_ALL(fn, params)  \
fn<uint8_t, bool>(params);  \
fn<uint8_t, char>(params);  \
fn<uint16_t, bool>(params); \
fn<uint16_t, char>(params); \
fn<uint32_t, bool>(params); \
fn<uint32_t, char>(params); \
fn<uint64_t, bool>(params); \
fn<uint64_t, char>(params);

template<typename A, typename B>
void test_number_one() {
   REQUIRE(...)
} 

TEST_CASE("Foo::Foo() works nicely", "[SmallGraph]") {
  RUN_ALL(test_number_one)
}

第一个故障,这是罚款,因为很可能所有8种情况都将以同样的方式失败。但是,当发生故障时,知道使用哪一组模板参数是很好的。我的想法是这样做:

This setup will run only until the first failure, which is fine because it is highly likely that all 8 cases will fail the same way. However, it would be nice to know which set of template arguments are in use when a failure occurs. My idea is to do this:

#define RUN_ALL_P(fn, params)  \
INFO("Testing <uint8_t, bool>"); \
fn<uint8_t, bool>(params);  \
INFO("Testing <uint8_t, char>"); \
fn<uint8_t, char>(params);  \
INFO("Testing <uint16_t, bool>"); \
fn<uint16_t, bool>(params); \
...

但是,我不能使用多个INFO RUN_ALL,因为这样会生成带有重复标识符的代码。

However, I can't use more than one INFO in RUN_ALL because doing so generates code with a duplicate identifier.

FOO.cpp:270:3: error: redefinition of 'scopedMessage270'
  RUN_ALL(test_number_one);

RUN_ALL(test_number_one)

有关不需要所有测试功能都具有相同签名的解决方案的任何想法?

Any ideas for a workaround that doesn't require all test functions to the same signature?

(我也欢迎指向有关使用CATCH测试模板代码的文章的指针,以及关于如何搜索此类文章而不获得关于一般异常的一系列结果的建议处理 - 即try / catch。)

(I would also welcome pointers to articles about testing template code using CATCH, as well as suggestions on how to search for such articles without getting a bunch of results about general exception handling -- i.e., try/catch.)

推荐答案


宏的问题是,扩展,它扩展到单行。虽然我不知道你的测试框架在使用,很明显,宏做了类似于这样的事情:

The problem with your macro is that, when it is expanded, it is expanded to a single line. Although I don't know your test framework in use, it is obvious that the macro does something comparable to this:

struct M { M(char* msg) { puts(msg); } }; // just an example class...
#define INFO(m) M scopedMessage##__line__(msg)


b $ b

所以你将得到多个scopedMessage270实例,如果你在第270行使用你的宏RUN_ALL ...

So you will get multiple scopedMessage270 instances, if you use your macro RUN_ALL at line 270...

你可以解决问题,与模板的宏。不幸的是,你不能使用模板函数,所以你也必须使你的测试用例模板类:

You could work around the problem by replacing the macro with a template. Unfortunately, you cannot use this with template functions, so you will have to make your test cases template classes, too:

template <template <typename T, typename TT > class Test >
struct All
{
    template <typename ... Parameters>
    static void run(Parameters ... parameters)
    {
        Test<uint8_t, bool>::run(parameters ...);
        Test<uint8_t, char>::run(parameters ...);
        Test<uint16_t, bool>::run(parameters ...);
        Test<uint16_t, char>::run(parameters ...);
        Test<uint32_t, bool>::run(parameters ...);
        Test<uint32_t, char>::run(parameters ...);
        Test<uint64_t, bool>::run(parameters ...);
        Test<uint64_t, char>::run(parameters ...);
    }
};

template<typename A, typename B>
struct test_number_one
{
    static void run()
    {
        // log test name
        // run the test
    }
};
template<typename A, typename B>
struct test_number_two
{
    static void run(int n)
    {
        // log test name and parameter value
        // run the test
    }
};

int main(int argc, char* argv[])
{
    All<test_number_one>::run();
    All<test_number_two>::run(12);
    All<test_number_two>::run(10);
}

现在,在模板中,所有代码行保留在单独的行可以放在任何日志之间,只要你喜欢:

As now, within the template, all code lines remain on separate lines, you can place in between any logging just as you like:

template <typename ... Parameters>
static void run(Parameters ... parameters)
{
    INFO("uint8_t, bool");
    Test<uint8_t, bool>::run(parameters ...);
    INFO("uint8_t, char");
    Test<uint8_t, char>::run(parameters ...);
// ...

这篇关于使用Catch框架测试C ++模板类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆