解析器的单元测试

时间:2012-03-05 15:41:41

标签: unit-testing testing

如何为以下场景编写单元测试?

要测试的程序是一个解析器,它可以识别输入中的不同结构。您可以将其视为解析标记语言。

核心问题是在某些模式匹配时识别文本中的结构。在实践中,这些不是正则表达式,但对于这个问题,将它们视为这样的问题应该没问题。

问题

假设我想要识别房间号码并且有一个模式p来匹配它们在输入的部分中与一组模式中的任何其他模式p2不匹配(例如,我想象的输入文档的页眉和页脚部分)

我可以想象编写单元测试,期望为给定的输入找到几个房间号。然而,提出好的测试,特别是边境案例,在这里确实存在问题。

测试:

有趣的测试用例应该以某种方式考虑不同的模式组合。特别是决定某些文本是否与琐碎的房间号码的模式匹配,以及更多的(授予的,仍然重要的)可用的单元测试。我可以区分几种测试:

1.:
"007" - expect: false
"01-001" - expect: true
"R02-33b" - expect: true
"01-001andsometext" - expect: false
"01-001 andsometext" - expect: true
"02-33X" - expect: false
"" - expect: false

2.:
"We meet in R01-001. Please invite agent 007." -- expect 1 matching rooms
"Excercise groups take place in 02-23b and 02-33c." --- expect 2 matches
... 

3.:
Integration test style. 
Long input with room numbers in the texts and in header/footer 
where I only want to recognize n rooms:
"... 150+ character string ..." - expect exactly 7 matches, 
                                  check if the right ones are matched

虽然第一个是一个非常精细的单元测试,它只能测试我程序中非常固定的部分,但也很容易忘记这些困难的情况。看看第二个例子,我可能会对自己说:“伙计,我应该真的包括一个测试案例,其中房间号码后跟一个句号,问号等。”

然而,第二个例子并不是真的好多了。特别是我仍然可以错过许多“边界情况”,因为解析器有很多(其他标点符号,Unicode等)。

但即便如此,我真正想要的不仅仅是检测某种格式的房间号,还要忽略那些处于“坏”部分的房间号码。测试解析“真实/典型”似乎是一个糟糕的单元测试练习:几乎不可读,预期的结果很容易改变我的程序的其他部分(设置“坏”模式)等等。

到目前为止我的结论

不知怎的,我想我会想要编写典型的单元测试 - 就像我的例子1一样。但是,我认为我需要很多不同类型的输入,但仍然会错过很多边界情况(例如unicode标点符号)除了我通常用于处理数字,树,图等的其他函数之外,所以我真的希望得到一些你有更多处理字符串输入经验的人的建议。

3 个答案:

答案 0 :(得分:1)

您可以使用几种信息来提出测试用例:

  • 要求文件。显然,您的代码应该能够处理这里提到的所有情况

  • 代码。阅读代码并问自己:执行这行代码需要什么样的输入?代码覆盖工具在这里有很多帮助。当测试用例执行代码的每一行以及所有if语句中每种可能的条件组合时,您应该完全覆盖您的理由

  • 考虑一下您的代码接受的输入。在解析数字时,这些输入如何:00..00.0.

  • 错误报告。最终,bug报告将会出现。由于错误报告本质上意味着“这是你通常会犯错误的东西”,每个错误报告都应该成为一个单元测试。

答案 1 :(得分:0)

在我看来和经验中,最好的方法是检查由单元测试创​​建的代码覆盖率。根据结果​​,您可以看到代码的哪些区域未经过测试,这为您提供了必须为其编写测试的提示。在这种情况下,你总会遇到一些问题,你可能会错过一些边缘案例。

答案 2 :(得分:0)

您考虑过data driven testing吗?在像你这样的情况下,不可能来测试所有可能的输入(好吧,什么时候真的可能?),并且有一些定义良好的输入数据可能会有所帮助。大多数现代测试框架(例如JUnitNUnit)都允许进行此类测试(例如,在文件/数据库中指定输入案例)。

我在这里打赌会对真正边缘的情况进行单独的测试(并且因为解析器通常是这样的通用工具,那些也可能从DDT中受益 - 除非你能提出非常具体的边缘情况,并且证明它的工作原理 - 简单地从一些较大的输入文件/数据源提供。