为单元测试编写复杂的预处理器宏
我正在使用一个单元测试套件,该套件可以劫持函数调用并测试预期的输出值。
正常的布局需要为每个期望值编写一个单元测试代码块。
由于我的代码使用了大量的枚举,我想使用一些 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,除了我需要替换字符串 < strong>默认为i的当前值。让我失望的是现有 EXPECTED_CALLS 宏中存在的引号和#。
I am working with a unit-testing suite that hijacks function calls and tests expected output values.
The normal layout requires one block of unit-testing code for each expected value.
Since my code makes use of a large number of enums, I would like to automate the automated-testing with some for loop / macro magic, and I'm looking for some advice with writing it.
Here is a block of the test code that I need to duplicate X number of times:
START_TEST("test_CallbackFn");
EXPECTED_CALLS("{{function1(param_type)#default}{function2(param_type)#default}}");
CallbackFn();
END_CALLS();
END_TEST();
Now, here is what I would envision occuring
for (int i = 0; i < 10; i++)
{
RUN_TEST(i)
}
Now, I would like to define RUN_TEST with the code I mentioned above, except I need to replace the string default with the current value of i. What is throwing me off is the quotes and #'s that are present in the existing EXPECTED_CALLS macro.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我想我会考虑使用单独的宏处理器,而不是试图击败 C 预处理器。人们指出的经典示例是 m4,但为此,您可能使用 awk 或 perl 或 python 做得更好代码> 或类似的东西。
I think I would look at using a separate macro processor rather than trying to beat the C preprocessor into submission. The classic example that people point to is
m4
, but for this, you might do better withawk
orperl
orpython
or something similar.根据我的经验,“复杂”+“宏观”=“不要这样做!”
C 预处理器并不是为执行如此强大的任务而设计的。虽然您可能能够做一些功夫并一起破解一些可行的东西,但使用脚本语言为您生成 C 代码会更容易(它也更容易调试,因为您可以通读生成的代码并确保它是正确的)。就我个人而言,我曾多次使用 Ruby 来完成此操作,但 Python、Perl、bash(等等)也应该可以。
In my experiences, "complex" + "macro" = "don't do it!"
The C preprocessor was not designed to do anything this powerful. While you may be able to do some kung-fu and hack something together that works, it would be much easier to use a scripting language to generate the C code for you (it's also easier to debug since you can read through the generated code and make sure it is correct). Personally, I have used Ruby to do this several times but Python, Perl, bash (etc etc) should also work.
我不确定我完全理解这个问题,但如果您希望
EXPECTED_CALLS
接收一个字符串,其中默认值被替换为任何默认值的字符串值,您需要删除#default< /code> 来自字符串。即
应该是
I'm not sure I fully understand the question, but if you want
EXPECTED_CALLS
to recieve a string where default is replaced with the string value of whatever default is you need to remove the#default
from the string. i.e.should be
这可能是可能的: Boost.Preprocessor 是确实令人印象深刻。
对于枚举来说可能有点困难,但是 Boost.Preprocessor 等中有 for every 循环。
使用外部脚本的生成方法的问题是它可能需要外部化的不仅仅是测试。除非您计划实现一个 C++ 解析器,而众所周知,即使在最好的情况下,这也是很棘手的……
所以您需要生成枚举(例如将它们存储在 json 中),以便之后能够生成这些枚举的测试。 ..事情开始变得棘手:/
It's probably possible: Boost.Preprocessor is quite impressive as it is.
For an enum it may be a bit more difficult, but there are for each loops in Boost.Preprocessor, etc..
The problem of the generative approach using external scripts is that it may require to externalize more than just the tests. Unless you plan on implementing a C++ parser which is known to be tricky at the best of times...
So you would need to generate the enums (store them in json for exemple) to be able to generate the tests for these enums afterward... and things begin to get hairy :/