为单元测试编写一个复杂的预处理器宏

问题描述:

我正在使用劫持函数调用并测试预期输出值的单元测试套件。为单元测试编写一个复杂的预处理器宏

正常的布局需要一个单元测试代码块的每个期望值。

由于我的代码使用了大量的枚举,我想用一些for循环/宏魔法自动执行自动测试,并且我正在寻找一些写它的建议。

下面是测试代码块,我需要重复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,除了我需要替换字符串默认与当前值。抛出我的是现有的EXPECTED_CALLS宏中存在的引号和#。

我想我会考虑使用一个单独的宏处理器,而不是试图击败提交的C预处理器。人们指出的经典示例是m4,但是对于此,您可能会用awkperlpython或类似的东西做得更好。

+0

同意,我们使用python从配置文件中生成大量的锅炉板C代码 - 我们现在可以使用模板完成所有工作,但很高兴能够看到代码是什么实际上在消失到编译器之前生成 – 2010-03-25 15:50:06

我不确定我是否完全理解这个问题,但是如果您希望EXPECTED_CALLS收到一个字符串,其中默认值被替换为任何默认值的字符串值,您需要从字符串中删除#default。即

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

应该

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

在我的经验, “复杂” + “宏”= “不这样做!” C预处理器并没有设计用来做任何强大的事情。虽然你可能能够做一些功夫并且一起破解一些可行的功能,但使用脚本语言为你生成C代码会容易得多(因为你可以读取生成的代码,所以它也更容易调试,确保它是正确的)。就我个人而言,我已经使用过Ruby多次,但Python,Perl,bash(等等)也应该工作。

它可能是:Boost.Preprocessor是相当令人印象深刻的,因为它是。

对于enum可能有点困难,但也有在Boost.Preprocessor每个回路等。

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

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