2012-03-05 66 views
2

我在这个周末为一个非平凡的语言写了一个解析器。某些输出可能很复杂,即使是看似简单的输入。假设解析器的输入是一个数学表达式,输出是描述输入的元组列表。你将如何测试复杂输出的东西?

所以输出可能是20行。

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

还是这只是疯了,我需要做一些不同的事情?

回答

4

理想情况下,“单元”测试的想法是它测试一个小功能单元。如果输出过于复杂以至于难以测试,那就意味着你正在测试的功能太大。

请记住,除了验证您的代码是否正常工作外,您的单元测试还可以充当您的代码应该如何使用的示例。一个单一的测试只是将结果与大的预定义结果进行匹配可能不会那样做。

尝试将内部运作分解为更小的方法并测试每个方法。尝试测试从较小的结果(例如,如果输入A导致输出Y,输入B导致输出Z,然后编写一个测试,以确定输入AB是否导致输出YZ或任何适当的结果)。

+0

解析器是递归下降。所以如果parse()调用一个()b()和c(),你建议我宁愿单元测试这些方法,或者他们调用什么等。但是,那么我会在哪里测试公共接口呢? – 2012-03-05 22:28:24

2

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

您将如何编写junit测试?你会运行解析器, 手动检查结果,如果它看起来正确,将结果放入 单元测试中作为正确答案?

使用JUnit进行集成测试和/或回归测试是完全有效的。我使用了很多时候描述的方法,但是您需要意识到这具有局限性。

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

  2. 在你的junit java类中有20行文本和输入是很痛苦的。所以你要面对在java中使用文本的选择,并把它们放入一个单独的文件中。大多数情况下,我发现单独的文件更易于管理,而且这些方法只是一个单独的文件,处理文件并将其与参考文件进行比较。

  3. 因为您正在进行集成测试,所以在遇到失败的测试时很难确定原因。

由于JacobM说,它可能是你的测试被拆下来到更小的碎片是个好主意,但你可以保留其他的测试,因为他们是有用的。