Ch 3. 软件测试的实质
本章从软件和实际的角度尝试解释软件测试的实质,理解为什么软件永远不会完美、必须学会取舍,从而了解软件测试的作用、影响和责任。
测试的原则
完全测试程序是不可能的
由于无法穷举所有可能的输入值、输出结果、执行路径,所有的测试都是有限的不完全测试。
此外,对软件说明书的理解这类主观因素的存在,也使得测试不可能完全。
软件测试是有风险的行为
根据上条原则,在实际的软件测试中必然选择不去测试所有的情况,这就引入了风险。
软件测试员必须学会的一个关键思想是:如何把数量巨大的可能测试减少到可以控制的范围,以及如何针对风险做出明智的抉择。换言之,哪些测试重要,哪些不重要。
测试无法显示潜伏的软件缺陷
测试只能证明软件中存在缺陷,但不能证明软件中不存在缺陷。仍然是第一条原则所述的那样,任何情况下都不可能保证软件是完全没有缺陷的。
唯一的方法是继续测试,也许还能找到一些。
找到的缺陷越多,说明实际上缺陷更多
这条可能读起来让人摸不着头脑,但实际上想想就会发现是显而易见的。
软件缺陷就像它的名字(Bug)一样,当你在家中发现一两只臭虫时,你就会意识到家中可能有更多的臭虫。根据第一条和第三条原则,这条原则是符合逻辑的。它指出了缺陷之间的相关性。
一般而言,我们有如下事实:
- 程序员也会有心情不好的时候。 这是自然,人无完人,程序员也不例外。当程序员心情不好时,他们的工作效率会降低,这就意味着他们可能会犯更多的错误。一个软件缺陷表明很可能附近还有更多的缺陷。
- 程序员往往犯相同的错误。 每个人都有习惯,人们总是常常落入自己曾经受困的陷阱;此外,对于背景类似、技能水平类似的程序员,他们之间也会共享一些相同的错误。
闭上眼睛,想想你在写第一个 C 语言程序的时候。忘加分号,写出 mian
函数……这些你曾经犯过的错误,你的同学、你的朋友,他们也曾经犯过。
——这就是人类的共性。
历史给我们的教训是,人们从来都不知道汲取历史的教训。
- 某些软件缺陷实乃冰山一角。 当某些基础性的组件或设计出现问题时,它们会随之影响整个软件系统。这就是为什么有时候一个小小的缺陷会引发一连串的问题。
杀虫剂怪事
这是一条有关软件测试的有趣的原则。它指出了软件测试的非线性特性。
就像自然选择为臭虫提供了抗药性一样,软件测试也会为软件缺陷提供某种无形的“免疫力”。总是使用同一种测试手段,软件缺陷就会表现出——注意,是表现,这里不存在实质上的因果关系——抵抗力。
和人们对抗药性和自然选择的误解一样,并非测试行为本身会使软件缺陷变得更难被发现,而是软件缺陷本身的性质使得它们更难被发现。只不过,测试这一选择性行为筛去了那些容易被发现的缺陷,留下了那些难以被发现的缺陷。
这条原则要求测试员们不断采取新的测试手段,对程序的不同部分进行测试。
并非所有缺陷最后都要修复
不同测试的目的是项目小组和软件测试员决定的。有时候,一个缺陷可能被认为是不重要的,或者是不值得修复的。
一般来说,我们有这些原因:
- 成本问题:无论是时间还是金钱,修复缺陷都是有成本的。有的时候,现实情况不允许我们付出这么多成本。同时,修复缺陷的成本也许远远超过了缺陷本身的影响。
- 修复的风险太大:软件本身是脆弱的,修改软件可能冒很大的风险:修复一个缺陷可能引发更多的缺陷。这就是所谓的遗留代码。
- 不算真正的软件缺陷:这是一个有趣的原因。就像游戏社区中常常调侃的那样,“这不是 bug,是 feature”。有时候,软件缺陷可能是某种刻意的不完美设计,或者它无意间能够负负得正、产生意想不到的好效果。
- 不值得修复: 这和第一条有些相似。有的时候我们必须权衡,也许某个错误在某个特定情况下才会出现,而这个情况(也就是前置条件)又是极少发生的。这时候,我们可能会选择不修复这个缺陷。
这条原则并不是作为测试员的你做出错误决策的免死金牌。
以不值得修复为例,这实际上是非常主观的。当你或开发小组认为这个缺陷不值得修复时,有可能你正在为未来埋下巨大的隐患。不幸的是,和人生中的许多选择一样,只有时间才能证明你的选择是否正确。
什么时候才叫缺陷难以说清
这条原则指出了软件缺陷的主观性。
本书中严格遵循第一章中给出的软件缺陷五大原因。这种情况下,我们的一个推论是:只有被看见的缺陷才能真正算作缺陷;而尚未发现或未观察到的缺陷只能说是潜在缺陷。
这个问题也许永远都没有答案——想想那个老问题:
森林里的一棵树倒下,但无人听见,它是否发出声音?
在软件测试的实践里,我们不必纠结于唯物主义和唯心主义的哲学思辨,去和同行聊聊,或许能找到一些启示。
产品说明书永远没有最终版本
这条原则指出了软件开发的动态性。就像之前所说,计划永远赶不上变化。如果软件开发墨守成规,坚持不引入变更,那么终将被市场淘汰。
作为测试员,我们必须意识到,产品说明书的变更是不可避免的。未经测试的功能会增加,经过测试的功能也可能被修改或删除。