我目前正在通过“美丽的球拍”工作,尝试编写单元测试。
单元测试宏的最佳方法是什么?例如,如果我有一个宏infix
:
(define-macro (infix [A B C]) #'(B A C))
测试模式匹配和转换的最明智的方法是什么?我想做类似的事情:
(check equal? (infix '(3 - 2)) '(- 3 2))
答案 0 :(得分:5)
通过测试宏的扩展来进行单元测试几乎永远不是您想要的。这有点像使用模拟测试所有内容,最终导致很多测试与实现紧密结合,而某些东西甚至不一定保证其行为。
因此,在测试宏时,您几乎总是只想通过验证宏是否确实在做正确的事情(而不是扩展到的内容)来进行测试。对于您的宏,我只需要编写一些测试用例,如下所示:
(check-equal? (infix (3 - 2)) 1)
(check-equal? (infix (4 / 2)) 2)
对于执行更复杂功能的宏,我仍然建议不要对扩展进行断言。如果需要,请在此处使用现有的单元测试工具包。即使在测试宏时,也应用相同的原理:使用依赖注入来替换难以测试的事物,并且如果需要,为单元测试提供一个稍低一点的接口,该接口与其协作者没有那么紧密的联系。 / p>
在确实需要进行更细粒度的单元测试的情况下,phase1-eval
中的syntax/macro-testing
可能会有所帮助,因为它允许您评估在编译时定义的函数。您的测试套件。就是说,我敦促您尽可能少地这样做。在使用Racket的过程中,我编写了一些非常密集的宏,并且设法在不进行扩展的情况下对其进行了行为测试。