Junit 您将如何测试具有复杂输出的东西?

Junit 您将如何测试具有复杂输出的东西?,junit,Junit,这个周末,我为一种非平凡的语言编写了一个解析器。有些输出可能很复杂,即使是看似简单的输入。假设解析器的输入是一个数学表达式,输出是描述输入的元组列表 因此,输出可能有20行长 您将如何编写junit测试?您是否会运行解析器,手工检查结果,如果结果正确,将结果作为正确答案放入单元测试中 还是说这太疯狂了,我需要做些不同的事情?理想情况下,“单元”测试的概念是测试一个小的功能单元。如果输出非常复杂,很难测试,这意味着您测试的功能单元太大 请记住,除了验证代码是否工作之外,单元测试还可以作为如何使用代

这个周末,我为一种非平凡的语言编写了一个解析器。有些输出可能很复杂,即使是看似简单的输入。假设解析器的输入是一个数学表达式,输出是描述输入的元组列表

因此,输出可能有20行长

您将如何编写junit测试?您是否会运行解析器,手工检查结果,如果结果正确,将结果作为正确答案放入单元测试中

还是说这太疯狂了,我需要做些不同的事情?

理想情况下,“单元”测试的概念是测试一个小的功能单元。如果输出非常复杂,很难测试,这意味着您测试的功能单元太大

请记住,除了验证代码是否工作之外,单元测试还可以作为如何使用代码的示例。仅将结果与大型预定义结果进行匹配的单个测试可能无法做到这一点


尝试将内部工作分解为更小的方法,并对每个方法进行测试。试着从较小的结果中建立一个结果(例如,如果输入a导致输出Y,输入B导致输出Z,那么编写一个测试,测试输入AB是否导致输出YZ,或者任何适当的结果)。

这是一个完全有效的测试,但不一定是一个单元测试。这趋向于集成测试或回归测试:

您将如何编写junit测试?请运行解析器, 手动检查结果,如果结果正确,将结果放入 单元测试是正确答案吗

使用JUnit进行集成测试和/或回归测试是非常有效的。我使用的方法您已经描述了很多次,但您需要意识到这有局限性

  • 除非你很小心,否则你的测试结果会很脆弱。例如,您的输出可能包含意外的字符(如果您混合使用unix和windows机器,则空格、cr/lf和编码是一个特别的问题)。这使得测试稍微复杂一些,因为您必须“清理”解析器的输出

  • 在JUnitJava类中有20行文本以及输入是一件痛苦的事情。因此,您需要选择将文本放在java中,或者将它们放在一个单独的文件中。大多数情况下,我发现单独的文件更容易管理,方法是一行,它获取一个文件,处理它,并将其与参考文件进行比较

  • 因为您正在进行集成测试,所以在测试失败时更难确定原因


  • 正如JacobM所说,将测试拆分为更小的部分可能是个好主意,但您可以离开其他测试,因为它们也很有用。

    解析器是递归下降的。因此,如果parse()调用a()b()和c(),您建议我改为更喜欢单元测试这些方法,或者它们调用什么等等。我对此不感兴趣。但是,如果我确实在测试公共接口,那么什么是更高级别的测试呢?