编写复杂的预处理器宏以进行单元测试

时间:2010-03-25 15:34:50

标签: c macros c-preprocessor

我正在使用一个单元测试套件,它劫持函数调用并测试预期的输出值。

正常布局需要一个单元测试代码块用于每个预期值。

由于我的代码使用了大量的枚举,我想用一些for loop / macro魔法自动化自动化测试,我正在寻找一些写作的建议。

以下是我需要复制X次的测试代码块:

START_TEST("test_CallbackFn");

EXPECTED_CALLS("{{function1(param_type)#default}{function2(param_type)#default}}");

CallbackFn();

END_CALLS();
END_TEST();

现在,我想到的就是

for (int i = 0; i < 10; i++)
{
  RUN_TEST(i)
}

现在,我想用上面提到的代码定义RUN_TEST,除了我需要用 i 的当前值替换字符串 default 。什么让我失望的是现有EXPECTED_CALLS宏中的引号和#。

4 个答案:

答案 0 :(得分:2)

我想我会考虑使用单独的宏处理器,而不是试图击败C预处理器。人们指出的典型示例是m4,但为此,您可以使用awkperlpython或类似内容做得更好。

答案 1 :(得分:1)

根据我的经验,“复杂”+“宏”=“不要这样做!”

C预处理器的设计并不是为了做这么强大的事情。虽然你可以做一些功夫和黑客一起工作,但是使用脚本语言为你生成C代码要容易得多(它也更容易调试,因为你可以阅读生成的代码和确保它是正确的)。就个人而言,我曾多次使用Ruby来做这件事,但是Python,Perl,bash(等等)也应该可以工作。

答案 2 :(得分:0)

我不确定我是否完全理解这个问题,但如果您希望EXPECTED_CALLS收到一个字符串,其中默认值替换为默认值的字符串值,则需要从#default中删除EXPECTED_CALLS("{{function1(param_type)#default}{function2(param_type)#default}}"); 字符串。即。

EXPECTED_CALLS("{{function1(param_type)"#default"}{function2(param_type)"#default"}}"); 

应该是

{{1}}

答案 3 :(得分:0)

可能有可能:Boost.Preprocessor令人印象深刻。

对于枚举,它可能有点困难,但Boost.Preprocessor等中的每个循环都有。

使用外部脚本的生成方法的问题是它可能需要外部化而不仅仅是测试。除非你打算实现一个C ++解析器,这个解析器在最好的时候都很棘手......

所以你需要生成枚举(将它们存储在json中作为例子)以便能够在以后生成这些枚举的测试......并且事情开始变得毛茸茸:/