4

我正在使用 Boost::Test 框架为比较函数编写单元测试。对于每个测试用例,我创建一系列输入元素并成对比较它们以检查每对比较函数的返回值。我可以手动写出来,也可以写一个函数。在单元测试中编写函数并不好,因为当出现故障时我们得到的有用信息较少。手动写出每个检查会导致非常长的单元测试。所以我决定使用宏来遍历要检查的元素。它看起来像这样:

#define CHECK_NODE_LESS(less, more) do {\
        BOOST_CHECK_EQUAL(compareQueueUnderTest((less), (more)), true); \
        BOOST_CHECK_EQUAL(compareQueueUnderTest((more), (less)), false); \
} while (false)

#define CHECK_NODE_ORDER_ELEMENT(r, elem1, elem2) CHECK_NODE_LESS(elem1, elem2);

#define CHECK_NODE_ORDER_INNER_LOOP(r, list, i, elem) \
        BOOST_PP_SEQ_FOR_EACH(CHECK_NODE_ORDER_ELEMENT, elem, \
                        BOOST_PP_SEQ_REST_N(i, list))

#define CHECK_NODE_ORDER(nodes) \
        BOOST_PP_SEQ_FOR_EACH_I(CHECK_NODE_ORDER_INNER_LOOP, \
                        BOOST_PP_SEQ_TAIL(nodes), nodes)

在部分排序但没有全部排序的测试用例中,我CHECK_NODE_LESS在适当的元素上使用宏来检查排序的元素,它工作正常。在总排序的测试用例中,我使用CHECK_NODE_ORDER宏。例如:

CHECK_NODE_ORDER((node1)(rootNode1)(node2)(rootNode2));

现在这个没有编译。我测试的第一件事是注释掉CHECK_NODE_LESS宏并运行预处理器以查看生成的内容。这是我所期望的:CHECK_NODE_LESS被要求使用正确的元素。然后我重新引入CHECK_NODE_LESS并运行预处理器,看看会发生什么。结果真的很丑,因为Boost Test中使用了宏,但是可以看出有些宏没有展开。

最后,我更改CHECK_NODE_LESS为以下内容,现在它工作正常:

#define CHECK_NODE_LESS(less, more) do {\
        BOOST_CHECK(compareQueueUnderTest((less), (more))); \
        BOOST_CHECK(!compareQueueUnderTest((more), (less))); \
} while (false)

我认为问题在于当我与其他宏一起使用时,Boost Preprocessor 库中存在一些迭代限制BOOST_CHECK_EQUAL,或者编译器中存在预处理器深度限制(我使用 Clang 3.4)。这个限制是多少,我该如何增加它?

4

1 回答 1

4

好主。

很可能没有人在 Boost.Test 上考虑过你想要做什么。问题不是编译器限制,而是BOOST_PP_SEQ_FOR_EACH不可重入并且BOOST_CHECK_EQUAL使用它。因此,无法使用BOOST_CHECK_EQUALinside 。有效,因为它不使用.BOOST_PP_SEQ_FOR_EACHBOOST_CHECKBOOST_PP_SEQ_FOR_EACH

我建议这种解决方法:

#define CHECK_NODE_ORDER_INNER_LOOP(r, list, i, elem) \
    BOOST_PP_LIST_FOR_EACH(CHECK_NODE_ORDER_ELEMENT, elem, \
                           BOOST_PP_SEQ_TO_LIST(BOOST_PP_SEQ_REST_N(i, list)))

我知道仅出于嵌套循环的目的而将序列转换为列表是相当难看的。在我的辩护中,这是我能想到的最不丑陋的方法。

于 2014-11-25T13:11:32.960 回答