你测了多少?你测全了吗?
虽然这类问题有点儿天真,但是客户希望了解你的测试覆盖。这个问题中隐藏了客户和很多测试人员都可能没有理解的巨大复杂性。回答这类问题的困难程度令人诧异,并且有可能将我们和客户陷入圈套。
假设,我们将“完整测试”定义为“执行了所有可能的测试用例”。大多数人马上就会想到,这个目标是不可能完成的。因此,当一个讲道理的人问:“你测完这个特性了吗?”或者“你测了多少了?”,他们肯定在考虑其他的一些事情。也许是“你是否已经确认了所有我们预料到的重要风险?”,或者是“你是否发现了我们没有预料到的所有重要问题?”,还有可能是“你是否在各种不同的平台上进行了测试?”,或者“你是否测试了所有用户接口?”,更有可能的是,他们只是简单地想知道“你测了什么?没测什么?”
在《软件测试技术》一书中,Boris Beizer将覆盖定义为“相对选定测试标准的任何完整性度量”。当我们选定的测试标准可以计量时,可以得到某些启示:如果软件有10W行代码,我们测试了其中的8W行,这意味着还有代码没有覆盖。为了检测未覆盖的代码,我们可以使用代码覆盖率工具。工具会告诉我们,在执行测试时碰到了(或者没碰到)哪些语句或者分支,哪些没有碰到的代码,可能是重要的。有些人认为,如果我们使用某些特定的数据,碰到了某行代码一次,那么它就被“覆盖”了。但是,工具不会,也不能回答我们寻找到了什么,我们搜索地有多仔细,我们观察到了什么,以及我们漏掉了什么。我们可以执行测试,确认执行了特定函数,执行了特定的路径,输入了特定的数据,以及返回了期望的结果,但是在做这些的同时,我们可能会轻易漏掉与其他数据、易用性、健壮性、安全性、性能、平台兼容、时间等等相关的问题。
还有一些其他的问题。代码覆盖率工具不能理解我们的思路,也不能领会产品的意图。工具不能确定所测试的代码是否执行了我们关心的功能,也不能识别是否丢失了价值。此外,源代码没有给我们整个蓝图,因为程序只是系统的很少一部分。我们的软件将与其他软件和硬件交互,有时甚至会超出我们能够理解的范围。在STARWest2007的一个演讲中,Lee Copeland指出,在有限的理解下,我们无法定义对复杂系统行为的覆盖率。当产品与其他系统、第三方软件、通过网络连接到的更多系统交互时,这个问题无可避免地被其自身所复制和扩散。对于这类系统,我们无法理解100%是什么,也就无从得知目前覆盖的完整性。我们可以对一个封闭系统这样做,但是当软件与外部交互时,就构成了一个不再封闭的系统。
不过,有一个可以逃离圈套的方法:建模。模型是一些概念、行为或者对象,描绘了某个事物——另一些概念、行为或者对象,因此,理解模型可以有助于理解其所“复现”的事物。为了更聚焦于我们所关心的信息,模型隐藏,或者忽略了某些信息。在长篇大论(但很有趣)地对代码行度量的攻击中,Beizer指出了很多颇有价值的建模代码及其结果的方法。例如,我们可以画出程序中的控制流、状态机,或者逻辑结构,然后执行程序来覆盖这些蓝图——这是更为可靠的测试完整性度量。
源代码是软件的一个模型,但软件不仅是代码。Cem Kaner提出,软件不仅是“计算机的一组指令”,而是“一些在时间、空间上隔离的人和计算机之间的联系,包含可以由计算机运行的指令。”,同时“软件的本质是向利益干系人提供价值”。这也解释了为什么代码覆盖和测试覆盖不是一会儿事。测试执行包括了使用某种方法,配置、操作、观察和评估产品,在这个过程中产生了对代码的覆盖。但客户并不关心代码,他们关心代码为他们做的事情。这也是当他们问“你测了多少?”时,真正想知道的答案。测试的价值在于我们的观察和评估,因此,如果我们希望理解、解释、讨论或者改进覆盖率时,我们需要一组丰富的模型。
当我们试图评估或者提升测试覆盖率时,第一步是回答:谁有兴趣?他们关心的是什么?即,确定为了谁覆盖,覆盖什么。卓越的测试从质疑目标开始。我们的起点越高,就能够营造更好的环境,来识别值得去观察的事情。因此,考虑“Higher -> Hire”:
- 他们为什么雇用我们?
- 谁是我们的客户?
- 谁会直接或间接使用产品?
- 谁是其他的利益干系人?
- 这轮测试我们的目标是什么?
- 项目和产品的总体目标是什么?
- 其他人对产品有什么看法?
- 产品的历史是什么样的?
- 是否有类似产品,竞争产品,或者历史版本?
这些问题有助于我们理解环境,并且将我们的注意力聚焦在重要的事情上,同时也可以识别不重要的事情。正如Donald Rumsfeld所言:“我们理解,既有已知的未知,也有未知的未知。”测试的一个关键目标是在我们所知道的方向上,去除我们不知道的东西。已知的“未知”隐藏了风险,但是,最大的风险也许来自未知的“未知”。
开始减少“未知”的最高效方法是学习其他人的“已知”。走近你的客户,开始提问。从“我可以问一些问题吗?”开始,如果答案是肯定的,那就开始问吧!如果答案是否定的,列出你不清楚的情况,以及缺乏信息带来的风险,可能会很有用,记录下来,不要忘记日期和时间。
如果客户乐于回答问题,但不清楚有哪些内容,你可以提供一些建议作为线索,询问他们是否关心。如果你倾向于从确认功能的正确性开始,这很好,但是很快,你也许就会希望扩展你的模型,来思考其他类型的问题和风险,以及你如何来覆盖它们。
感悟:你测了多少,这不是一个计算题,而是一个论述题,需要测试人员通过丰富的模型、持续的交流来汲取他人的知识,更需要测试人员有一颗勇于探索“未知”的心。
注:本文译自Michael Bolton的《Got You Covered》。参见:http://www.developsense.com