C++ Unit Testing Legacy Code: How to handle #include?我刚刚开始使用#include指令为具有较大物理依赖性的旧版代码模块编写单元测试。 我一直在与他们进行一些过分乏味的处理(提供空标头来打破较长的#include依赖项列表,并使用#define防止类被编译),并且正在寻找一些更好的策略来处理这些问题。 我经常遇到这样的问题:几乎将每个头文件都复制为空白版本,以完整地分离出我正在测试的类,然后为需要被处理的对象编写大量的stub / mock / fake代码。 已替换,因为它们现在不 有人知道一些更好的做法吗? 响应中的压抑感是压倒性的...但是,不用担心,我们拥有一本神圣的书,可以驱除遗留C ++代码的魔鬼。如果您排队使用传统C ++代码超过一个星期,请认真购买本书。 转到第127页:可怕的包含依赖项。 (现在,我什至不在迈克尔·费瑟斯(Michael Feathers)的距离之内,但在这里我可以尽我所能地回答。。) 问题:在C ++中,如果ClassA需要了解ClassB,则Class B的声明直接/文本包含在ClassA的源文件中。而且由于我们的程序员喜欢将其带到错误的极端,因此文件可以递归地包含成千上万个其他文件。构建需要数年..但是,至少它可以构建..我们可以等待。 现在说"很难在测试工具下实例化ClassA"是轻描淡写的。 (引用MF的示例-Scheduler是我们的海报问题孩子,拥有丰富的经验。)
这将带出一系列错误的包含龙。
而pop依赖项及其所有可传递的包含项。 警告(我提到有警告吗?:)
将此技术用于具有严重依赖问题的非常庞大的类。不要经常使用或轻描淡写。。以此为基础进行更深入的重构。随着时间的推移,当您提取更多的类时(通过他们自己的测试),可以将该测试程序带到谷仓后面。 有关更多信息,请阅读本书。无价。加油!
我不知道这是否适用于您的项目,但
这将完全消除您的#include问题。 这种方法的最大缺点是构建系统更加复杂。 我不是直接回答您的问题,但是我担心如果您使用大量的旧代码,就不能做单元测试。 在带领XP团队进行绿色开发项目之后,我真的很喜欢我的单元测试。事情发生了,几年后,我发现自己正在处理大量质量问题的大型遗留代码库。 我试图找到一种向应用程序添加单元测试的方法,但最终陷入了22个陷阱: 如果您觉得自己像个英雄,并且在单元测试中喝了些辅助工具,那么您仍然可以尝试一下,但是确实有风险,您最终只能获得更多价值不大的测试代码,现在还需要维护这些代码。 有时,最好以"设计"的方式来处理代码。 由于您正在测试旧版代码,因此我假设您无法重构所述代码以减少依赖(例如,使用pimpl习惯用法) 恐怕您别无选择。类型或函数包含的每个标头都需要该类型或函数的模拟对象才能编译所有内容,您几乎无能为力。 拥有大量依赖关系的遗留代码绝对会让您陷入困境。您需要花很长时间才能解决所有问题。 从您所说的看来,您似乎试图依次保持每个模块的源代码完整,将其放置在模拟了外部依赖项的测试工具中。我的建议是采取更加勇敢的步骤,尝试进行一些重构以消除(或反转)依赖关系,这也许就是您要避免的步骤。 我建议这样做是因为我猜这些依赖会在您编写测试时杀死您。如果可以消除依赖关系,从长远来看,您一定会过得更好。 如果您继续编写存根/模拟/伪代码,则可能要对行为不同的类进行单元测试,然后再对主项目进行编译。 但是,如果其中包含这些内容并且没有其他行为,那就可以了。 在进行单元测试时,我会尽量不更改include上的任何内容,因此可以确保(到目前为止,您可以使用旧版代码:))测试实际代码。 |