我刚刚重温了经典的C语言教科书K&R。并阅读练习1-11:
你如何测试字数统计程序?什么类型的输入最有可能发现bug(如果有的话)?
实际上,我只有一个基本的想法,即手动计算现有段落以获得确切的单词数,并将其与单词计数程序计算的结果进行比较。
我错过了什么吗?测试的诀窍是什么?
编辑
答案总结:
词的语义定义,一些特殊情况:
- 链接词:"cat-walk"
- 小字:a, b,c
- 字数:"a fooooooooo<40MILLIONLETTERS>ooooooo a"有3个字
边界条件:
- 单词之间有多个空格的文本。
- 大于2GB的文本
- 包含破折号但没有空格的单词。
- 非ascii字。
- 不同编码的文件(如果你的程序支持)
- 由空格包围但不包含任何单词字符的字符(例如:"hello - world")
- 不带文字的文本
- 单行文字
嗯,这取决于你在语义上将什么定义为单词。因为是你在写单词计数程序,你应该知道一个单词是什么。
因此,要测试这个程序,您必须考虑哪些极端情况:"链接的单词"算作一个单词还是两个单词?你认为"I'm"是一个还是两个?等至于K&R的练习,我猜他们是自愿忘记了一些边角的情况,他们建议您在分析他们的代码时找到这些警告。
下面是一些可以发现bug的文本示例:
- 单词之间有多个空格的文本。
- 大于2GB的文本
- 包含破折号但没有空格的单词。
- 非ascii字。
- 不同编码的文件(如果你的程序支持)
- 由空格包围但不包含任何单词字符的字符(例如:"hello - world")
- 不带文字的文本
- 单行文字
我没有重读练习1-11的答案…(我的书在60公里外)
可能编码错误的内容
- 小字:
"a b c d"
有4个字 - biiiiiiiingwords:
"a fooooooooo<40MILLIONLETTERS>ooooooo a"
有3个单词 - 使用的几个符号:
",.!? ...
可能不被理解的定义
-
"cat-walk"
1字?两个词? -
"under-nstood"
在单词 中间换行(带连字符)
要测试一个算法,您应该创建一组具有已知结果的测试用例。
这个测试用例应该包括:
- 最可能的输入组合;
- "边境"案件。在您的情况下,它可以是:一个单词,两个单词,许多分隔符,以分隔符开始和结束的短文本,等等; 一些奇怪的文字。看看这个算法,试着想想可能会破坏它的奇怪输入。通常它是一个非常小的文本(3-4)个单词,但它们之间有一些奇怪的分隔符,如
"hello,word", "hello ,word", "hello word,,,,"
其他人已经给出了一些非常实用的建议。让我补充两点:
首先,K&R不希望您发现他们代码的所有缺陷。练习的目标是让您意识到这样一个事实,即经常存在虚假输入,并且有朝一日您可能会在类似的情况下以某种方式处理它。你怎么做完全取决于你自己。只要记住,一些看似简单的问题有时需要认真思考。
以防万一:当我愚蠢的iPhone收到一条消息,上面写着"foo是bad。"它闻起来",它能识别"不好的东西。作为URL。看起来很有趣,但到目前为止,如果不更改消息内容本身,就无法修复此错误。
第二,你的标题有误导性。仅仅通过测试是不可能找到程序中的所有bug的。或者正如Edsger Dijkstra曾经说过的:
测试显示bug 存在,而不是不存在。
这是理论计算机科学的一个基本结果,实际上可以被证明。如果你感兴趣的话,请看Rice的定理。
编辑:在写这篇文章时,我发现了一个与我们的主题有关的bug: StackOverflow解析器不会识别"http://en.wikipedia.org/wiki/Rice's_theorem"作为URL。: -)
EDIT2:在这里提交了一个关于meta的bug报告。