我应该如何单元测试一个代码生成器?

29 投票
8 回答
8403 浏览
提问于 2025-04-10 23:38

我知道这个问题比较复杂,也没有明确的答案,但我想问问大家有没有什么有趣的建议。

我开发了一个代码生成器,它可以把我们用Python写的接口(通过SWIG生成的C++代码)转化成可以作为Web服务使用的代码。在开发这个代码的时候,我采用了测试驱动开发(TDD),但是我发现我的测试非常脆弱。因为每个测试基本上都是想验证给定的输入代码(其实是C++的头文件)能生成我期望的输出代码,所以我写了一个小引擎,从XML输入文件中读取测试定义,并根据这些期望生成测试用例。

问题是,我非常不想去修改代码。而且单元测试本身也有两个问题:一是复杂,二是脆弱。

所以我在考虑有没有其他的方法来解决这个问题,感觉我可能是走错了方向。也许我应该更关注结果,比如:我生成的代码是否真的能运行并完成我想要的功能,而不是它的外观是否符合我的期望。

有没有人有类似的经历愿意分享一下?

8 个回答

0

没错,结果才是最重要的。真正麻烦的是要写一个框架,让你生成的代码可以独立运行……把时间花在这上面吧。

5

首先要知道,“单元测试”只是测试的一种方式。你应该能够对代码生成器内部的部分进行单元测试。但这里你真正要关注的是系统级测试,也就是回归测试。这不仅仅是说法上的不同……它们在思维方式、方法、期望等方面都有差别。虽然这确实需要更多的工作,但你可能需要勇敢面对,建立一个端到端的回归测试套件:固定的C++文件 -> SWIG接口 -> Python模块 -> 已知的输出。你真正想要做的是将已知的输入(固定的C++代码)与预期的输出(最终Python程序的结果)进行对比。直接检查代码生成器的结果就像是在比较目标文件……

14

我开始写一段关于我自己代码生成器的经验总结,然后又回去看了你的问题,发现你已经提到过类似的问题了,重点是执行结果,而不是代码的排版或外观。

问题是,这个很难测试,生成的代码可能不适合在单元测试系统的环境中运行,那你怎么去编码预期的结果呢?

我发现你需要把代码生成器拆分成更小的部分,然后对这些小部分进行单元测试。如果你问我,测试一个完整的代码生成器更像是集成测试,而不是单元测试。

撰写回答