本周末我为一个非平凡的语言编写了一个解析器。即使对于看似简单的输入,一些输出也可能很复杂。假设解析器的输入是一个数学表达式,输出是描述输入的元组列表。
所以输出可能是20行。
你会怎么写junit测试?您是否会运行解析器,手动检查结果,如果看起来正确,请将结果作为正确的答案放入单元测试中?
或者这只是疯了,我需要采取不同的做法吗?
答案 0 :(得分:4)
理想情况下,“单元”测试的想法是测试一小部分功能。如果输出太复杂而难以测试,则意味着您测试的功能单元太大。
请记住,除了验证您的代码是否有效之外,您的单元测试还可以作为代码应如何使用的示例。将结果与大预定义结果匹配的单个测试可能不会这样做。
尝试将内部工作分解为更小的方法并测试每个方法。尝试测试从较小的结果建立结果(例如,如果输入A导致输出Y,输入B导致输出Z,则写入输入AB是否导致输出YZ的测试,或者是否是适当的结果)。
答案 1 :(得分:2)
这是一个完全有效的测试,但不一定是单元测试。这趋向于进行集成测试或回归测试:
你会怎么写junit测试?你会运行解析器, 手工检查结果,如果看起来正确,请将结果放入 单元测试作为正确答案?
使用JUnit进行集成测试和/或回归测试是完全有效的。我使用你在很多时候描述的方法,但你需要意识到这有局限性。
除非你小心,否则你的测试最终会变得非常脆弱。例如,您的输出可能包含意外字符(空格,cr / lf和编码是一个特殊问题,如果你混合unix和windows机器)。这使得测试稍微复杂一些,因为您必须“清理”解析器的输出。
在junit java类中有20行文本以及输入是很痛苦的。因此,您可以选择在java中使用文本,将它们放入单独的文件中。大多数时候,我发现单独的文件更容易管理,方法是一行,它接受一个文件,处理它并将它与参考文件进行比较。
因为您正在进行集成测试,所以在测试失败时更难确定原因。
正如JacobM所说,将测试分解为较小的部分可能是一个好主意,但你可以离开其他测试,因为它们也很有用。