设计测试用例的四条原则

发表于:2013-07-12来源:ulm.org.cn作者:quicknet点击数: 标签:测试用例
今天是2011年的第一天,2010年就这样匆匆忙忙,紧紧张张地过去了。这一年里来来去去,变化最大的就是很多一起工作了多年的同事离开了,很多都去了"更给力”的地方,呵呵!公司里来来往往是很正常的,想想我最近一次换到“更给力”的地方,那都是5年前了。总之

  今天是2011年的第一天,2010年就这样匆匆忙忙,紧紧张张地过去了。这一年里来来去去,变化最大的就是很多一起工作了多年的同事离开了,很多都去了"更给力”的地方,呵呵!公司里来来往往是很正常的,想想我最近一次换到“更给力”的地方,那都是5年前了。总之,现在的地方还是挺给力的,好好工作,争取2011年有更大的进步,呱唧呱唧!

  测试用例设计的最基本要求:覆盖住所要测试的功能。这是再基本不过的要求了,但别看只是简单的一句话,要能够达到切实覆盖全面,需要对被测试产品功能的全面了解、明确测试范围(特别是要明确哪些是不需要测试的)、具备基本的测试技术(如:等价类划分等)等。那么满足了上述这条要求是不是设计出来的测试用例就是好的测试用例了呢?答案:在理论上是,但在实际工程中还远远不是。之所以理论和实际会有这样的差别,是因为在理论上不要考虑的东东,而在实际工程中是不得不考虑的 - 成本。这里的成本包括:测试计划成本、测试执行成本、自动化测试用例、测试自动化成本,测试分析成本,以及测试实现技术局限、测试环境的Bug、人为因素和不可预测的随机因素等引入的附加成本等。

  由于成本因素的介入,决定了工程中设计好的测试用例原则不只有“覆盖住所要测试的功能”这一条,下面是我根据自己的工作经验总结出的其它四条原则,在这里抛砖引玉,希望大家拍砖和指正。这些原则特别是针对那些需要被自动化,并且是要被经常执行的测试用例。

  1. 单个用例覆盖最小化原则。

  这条原则是所有这四条原则中的”老大“,也是在工程中最容易被忘记和忽略的,它或多或少的都影响到其它几条原则。下面举个例子来介绍,假如要测试一个功能 A,它有三个子功能点 A1,A2 和 A3,可以有下面两种方法来设计测试用例:

  方法1 :用一个测试用例覆盖三个子功能 -Test_A1_A2_A3,

  方法2 :用三个单独的用例分别来覆盖三个子功能 - Test_A1,Test_A2,Test_A3

  方法1适用于规模较小的工程,但凡是稍微有点儿规模和质量要求的项目,方法2则是更好的选择,因为它具有如下的优点:

  测试用例的覆盖边界定义更清晰

  测试结果对产品问题的指向性更强

  测试用例间的耦合度最低,彼此之间的干扰也就越低

  上述这些优点所能带来直接好处是,测试用例的调试、分析和维护成本最低。每个测试用例应该尽可能的简单,只验证你所要验证的内容,不要“搂草打兔子”捎带着把啥啥啥啥都带进来,这样只会增加测试执行阶段的负担和风险。David Astels在他的著作《Test Driven Development:A Practical Guide》曾这样描述,最好一个测试用例只有一个Assert语句。此外,覆盖功能点简单明确的测试用例,也便于组合生成新的测试,在Visual Studio中就引入了Ordered Test的概念。

  2. 测试用例替代产品文档功能原则。

  通常我们会在开发的初期(Scrum每个Sprint的头两天)用Word文档或者OneNote的记录产品的需求、功能描述、以及当前所能确定的任何细节等信息,勾勒将要实现功能的样貌,便于团队进行交流和细化,并在团队内达成对产品功能共识。假设我们在此时达成共识后,描述出来的功能为A,随着产品开发深入,团队会对产品的功能有更新的认识,产品功能也会被更具体细化,在一个迭代或者Sprint结束的时候最终实现的功能很可能是A+。如此往复,在不断倾听和吸收用户的反馈,修改产品功能,多个迭代过后,原本被描述为A的功能很可能最终变为了Z。这是时候再去看曾经的Word文档和OneNote页面,却仍然记录的是A。之所以会这样,是因为很少有人会去(以及能够去)不断更新那些文档,以准确反映出产品功能当前的准确状态。不是不想去做,而是实在很难!这里需要注意:早期的Word或者OneNote的文档还是必要的,它至少能保证在迭代初期团队对要实现功能有一致和准确的认识。

  就没有什么东西能够一直准确地描述产品的功能了吗?答案:当然有,那就是产品代码和测试用例。产品代码实现了产品功能,它一定是准确描述了产品的当前功能,但是由于各种编程技术,如:面向对象、抽象、设计模式、资源文件等等,使得产品代码很难简单地就能读懂,往往是在知道产品功能的前提下去读代码,而不是反过来看代码来了解功能。好的代码会有详细的注释,但这里的注释是对实现代码的解释和备注,并不是对产品功能的描述。这里有一篇很老的博客 Reading Code Is Hard,介绍了如何能够使代码更可读一些编写技巧。

  那么就只有测试用例了,测试也应该忠实反映了产品功能的,否则的话测试用例就会执行失败。以往大家只是就把测试用例当作测试用例而已,其实对测试用例的理解应该再上升到另一个高度,它应该是能够扮演产品描述文档的功能。这就要求我们编写的测试用例足够详细、测试用例的组织要有调理、分主次,单靠Word、Excel或者OneNote这样通用的工具是远远无法完成的,需要更多专用的测试用例管理工具来辅助,例如 Visual Studio 2010引入Microsoft Test Manager。

  此外,对于自动化测试用例(无论是API或者UI级别的)而言,代码在编写上也应该有别产品代码编写风格,可读性和描述性应该是重点考虑的内容。在测试代码中,当然可以引入面向对象、设计模式等优秀的设计思想,但是一定要适度使用,往往面向过程的编码方式更利于组织、阅读和描述。

  3. 单次投入成本和多次投入成本原则。

  与其说这是一条评判测试用例的原则,不如说它是一条思考问题的思维角度和原则。成本永远是任何项目进行决策时所要考虑的首要因素,项目中的测试也是如此,对成本的考虑也应该客观和全面的体现在测试的设计、执行和维护的整个阶段中。当你在测试中遇到一些左右为难的问题需要决策时,尝试着从成本角度去分析一下,也许会对你的决策有所帮助。

  测试中的成本按其时间跨度可以分为:单次投入成本和多次投入成本。例如:编写测试用例可以看作是单次投入成本,因为编写测试用例一般是在测试的计划阶段进行(Scrum每个Sprint的开始阶段)的,虽然后期会有小的改动,但绝大多数是在一开始的设计阶段就基本上成型了;自动化测试用例也是如此,它也属于是一次性投入;测试用例(包括:手工和自动化测试用例)的执行则是多次投入成本,因为每出一个新版本Build时都要执行所有的测试用例(或者进行BVT测试仅执行高优先级的测试用例)、分析测试结果、调试失败测试用例、确定测试用例的失败原因(产品缺陷、测试用例缺陷、测试框架缺陷还是随机问题导致了测试用例的失败),以验证该版本整体质量是否达到了指定的标准。

原文转自:http://www.uml.org.cn/Test/201107202.asp