首页 > > > 软件测试的艺术.pdf

软件测试的艺术.pdf

软件测试的艺术.pdf

上传者: 摇曳 2013-04-02 评分1 评论0 下载58 收藏10 阅读量443 暂无简介 简介 举报

简介:本文档为《软件测试的艺术pdf》,可适用于IT书籍领域,主题内容包含TheArtofSoftwareTestingSecondEditionGlenfordJMyersRevisedandUpdatedbyTomBa符等。

The Art of Software Testing Second Edition Glenford J. Myers Revised and Updated by Tom Badgett and Todd M.Thomas with Corey Sandler Copyright 2004 by Word Association, Inc. All rights reserved. Published by John Wiley & Sons, Inc., Hoboken, New Jersey. Published simultaneously in Canada. 整理:丁兆杰,黄墀晖,黄米青,林嘉,马晓靖,王博,吴航,余华兵,俞培源 v.1.2 7/1/2008 未经同意,严禁以任何形式拷贝 ii 前言 1979 年 Glenford J.Myers 出版了一本现在仍被证明为经典的著作,这就是本书 的第 1 版。本书经受住了时间的考验,25 年来一直被列在出版商可供书目的清单中。 这个事实本身就是对本书稳定、基础和珍贵品质的佐证。 在同一时期,本书第 2 版的几位合著者共出版了 120 余本著作,大多数都是关 于计算机软件的。其中有一些很畅销,再版了多次(例如 Corey Sandler 的《Fix Your Own PC》自付印以来已出版到第 7 版,Tom Badgett 关于微软 PowerPoint 及其他 Office 组件的著作已经出版到第 4 版以上)。然而,这些作者的著作中没有哪一本书 能够像本书一样持续数年之后仍畅销不衰。 区别究竟在哪里呢?这些新书只涵盖了短期性的主题:操作系统、应用软件、 安全性、通信技术及硬件配置。20 世纪 80 年代和 90 年代以来的计算机硬件与软件 技术的飞速发展,必然使得这些主题频繁地变功和更新。 在此期间出版的有关软件测试的书籍已数以十计、甚至数以百计。这些书也对 软件测试的主题进行了简要的探讨。 然而,本书为计算机界一个最为重要的主题提供了长期、基本的指南:如何确 保所开发的所有软件做了其应该做的,并且同样重要的是,未做其不应该做的? 本书第 2 版中保留了同样的基本思想。我们更新了其中的例子以包含更为现代 的编程语言。我们还研究了在 Myers 编著本书第 1 版时尚无人了解的主题:Web 编 程、电子商务及极限编程与测试。 但是,我们不会忘记,新的版本必须遵从其原著。因此,新版本依然向读者展 示 Glenford Myers 全部的软件测试思想:这个思想体系以及过程将适用于当今乃至 未来的软件和硬件平台。我们也希望本书能够顺应时代,适用于当今的软件设计人 员和开发人员掌握最新的软件测试思想及技术。 iii 引言 在本书 1979 年第 1 版出版的时侯,有一条著名的经验,即在一个典型的编程 项目中,软件测试或系统测试大约占用 50%的项目时间和超过 50%的总成本。 25 年后的今天,同样的经验仍然成立。现在出现了新的开发系统、具有内置工 具的语言以及习惯于快速开发大量软件的程序员。但是,在任何软件开发项目中, 测试依然扮演着重要角色。 在这些事实面前,读者可能会以为软件测试发展到现在不断完善,已经成为一 门精确的学科。然而实际情况并非如此。事实上,与软件开发的任何其他方面相比, 人们对软件测试仍然知之甚少。而且,软件测试并非热门课题,本书首次出版时是 这样.遗憾的是,今天仍然如此。现在有很多关于软件测试的书籍和论文,这意味 着,至少与本书首次出版时相比,人们对软件测试这个主题有了更多的了解。但是, 测试依然是软件开发中的“黑色艺术”。 这就有了更充足的理由来修订这本关于软件测试艺术的书,同时我们还有其他 一些动机。在不同的时期,我们都听到一些教授和助教说;”我们的学生毕业后进 入了计算机界,却丝毫不了解软件测试的基本知识,而且在课堂上向学生介绍如何 测试或调试其程序时,我们也很少有建议可提供。” 因此,本书再版的目的与 1979 年时一样:填充专业程序员和计算机科学学生 的知识空缺。正如书名所蕴涵的,本书是对测试主题的实践探讨,而不是理论研究, 连同了对新的语言和过程的探讨。尽管可以根据理论的脉络来讨论软件测试,但本 书旨在成为实用且“脚踏实地”的手册。因此很多与软件测试有关的主题,如程序 正确性的数学证明都被有意地排除在外了。 本书第 l 章介绍了一个供自我评价的测试,每位读者在继续阅读之前都须进行 测试。它揭示出我们必须了解的有关软件测试的最为重要的实用信息,即一系列心 理和经济学问题,这些问题在第 2 章中进行了详细讨论。第 3 章探讨的是不依赖计 算机的代码走查或代码检查的重要概念。不同于大多数研究都将注意力集中在概念 的过程和管理方面,第 3 章则是从技术上“如何发现错误”的集度来进行探讨。聪 明的读者都会意识到,在软件测试人员的技巧中最为重要的部分是掌握如何编写有 未经同意,严禁以任何形式拷贝 iv 效测试用例的知识.这正是第 4 章的主题。本书第 5 章和第 6 章分别探讨了如何测 试单个模块或子程序及测试更夫的对象,而第 7 章则介绍了一些程序调试的实用建 议,第 8 章讨论了极限编程和极限测试的概念,第 9 章介绍了如何将本书其他章节 中详细讨论的软件测试的知识运用到 web 编程,包括电子商务系统中去。 本书面向三类主要的读者。尽管我们希望本书中的内容对于专业程序员而言不 完全是新的知识,但它应增强专业人员对测试技术的了解。如果这些材料能使软件 人员在某个程序中多发现一个错误,那么本书创造的价值将远远超过书价本身。第 二类读者是项目经理,因为本书中包含了测试过程管理的最新的、实用的知识。第 三类读者是计算机科学的学生,我们的目的在于向学生们展示程序测试的问题,并 提供一系列有效的技术。我们建议将本书作为程序设计课程的补充教材,让学生在 学习阶段的早期就接触到软件测试的内容。 Glenford J . Myers Tom Badgett Todd M . Thomas Corey Sandler 目 录 第 1 章 一个自我评价测试 .......................................................................................1 第 2 章 软件测试的心理学和经济学 ..............................................................................4 2.1 软件测试的心理学 .............................................................................................4 2.2 软件测试的经济学 .............................................................................................7 2.3 软件测试的原则 ...............................................................................................11 2.4 小结 ...................................................................................................................15 第 3 章 代码检查、走查与评审 ....................................................................................16 3.1 检查与走查(Inspections And Walkthroughs) ...................................................17 3.2 代码检查(Code Inspections).............................................................................18 3.3 用于代码检查的错误列表 ...............................................................................20 3.4 代码走查(Walkthroughs) ..................................................................................29 3.5 桌面检查(Desk Checking) ................................................................................30 3.6 同行评分(Peer Ratings) ....................................................................................31 3.7 小结 ...................................................................................................................32 第 4 章 测试用例的设计 ................................................................................................33 4.1 白盒测试(White-Box Testing) ..........................................................................34 4 .2 错误猜测(Error Guessing) ...............................................................................68 4.3 测试策略 ...........................................................................................................70 第 5 章 模块(单元)测试 ............................................................................................71 5.1 测试用例设计 ...................................................................................................71 5.2 增量测试 ...........................................................................................................80 5.3 自顶向下测试与自底向上测试 .......................................................................84 5.4 执行测试 ...........................................................................................................91 第 6 章 更高级别的测试 ................................................................................................93 6.1 功能测试(Function Testing)..............................................................................98 6.2 系统测试(System Testing) ................................................................................99 6.3 验收测试(Acceptance Testing) .......................................................................109 6.4 安装测试(Installation Testing)........................................................................109 未经同意,严禁以任何形式拷贝 6 6.5 测试的计划与控制 .........................................................................................110 6.6 测试结束准则 .................................................................................................112 6.7 独立的测试机构 .............................................................................................117 第 7 章 调试(DEBUGGING)........................................................................................118 7.1 暴力法调试(Debugging by Brute Force)........................................................119 7.2 归纳法调试(Debugging by Induction) ...........................................................120 7.3 演绎法调试(Debugging by Deduction) ..........................................................123 7.4 回溯法调试(Debugging by Backtracking) .....................................................126 7.5 测试法调试(Debugging by Testing) ...............................................................126 7.6 调试的原则 .....................................................................................................127 第 8 章 极限测试 ..........................................................................................................131 8.1 极限编程基础 .................................................................................................131 8.2 极限测试:概念 .............................................................................................135 8.3 极限测试的应用 .............................................................................................137 8.4 小结 .................................................................................................................141 词汇表 ............................................................................................................................142 软件测试的艺术 未经同意,严禁以任何形式拷贝 1 第 1 章 一个自我评价测试 自本书 25 年前首次出版以来,软件测试变得比以前容易得多,也困难得多。 软件测试何以变得更困难?原因在于大量编程语言、操作系统以及硬件平台的 出现。在 20 世纪 70 年代只有相当少的人使用计算机,而今天在商业界和教育界, 如果不使用计算机,几乎没有人能完成日常工作。况且,计算机本身的功能也比以 前增强了数百倍。 因此,我们现在编写的软件会潜在地影响到数以百万计的人,使他们更高效地 完成工作,反之也会给他们带来数不清的麻烦,导致工作或事业的损失。这并不是 说今天的软件比本书第一版发行时更重要,但可以肯定地说,今天的计算机——以 及驱动它的软件——无疑已影响到了更多的人、更多的行业。 就某些方面而言,软件测试变得更容易了,因为大量的软件和操作系统比以往 更加复杂,内部提供了很多已充分测试过的例程供应用程序集成,无须程序员从头 进行设计。例如,图形用户界面(GUI)可以从开发语言的类库中建立起来,同时, 由于它们是经过充分调试和测试的可编程对象,将其作为用户应用程序的组成部分 进行测试的要求就减少了许多。 所谓软件测试,就是一个过程或一系列过程.用来确认计算机代码完成了其应 该完成的功能不执行其不该有的操作。软件应当是可预测且稳定的,不会给用户带 来意外惊奇。在本书中,我们将讨论多种方法来达到这个目标。 好了,在开始阅读本书之前,我们想让读者做一个小测验。 我们要求设计一组测试用例(特定的数据集合),适当地测试一个相当简单的 程序。为此要为该程序建立一组测试数据,程序须对数据进行正确处理以证明自身 的成功。下面是对程序的描述: 这个程序从一个输入对话框中读取三个整数值。这三个整数值代表了 三角形三边的长度。程序显示提示信息,指出该三角形究竟是不规则三角 第 1 章 一个自我评价测试 未经同意,严禁以任何形式拷贝 2 形、等腰三角形还是等边三角形。 注意,所谓不规则三角形是指三角形中任意两条边不相等,等腰三角形是指有 两条边相等,而等边三角形则是指三条边相等。另外,等腰三角形等边的对角也相 等(即任意三角形等边的对角也相等),等边三角形的所有内角都相等。 用你的测试用例集回答下列问题,借以对其进行评价。对每个回答“是”的答 案,可以得 l 分: 1. 是否有这样的测试用例,代表了二个有效的不规则三角形?(注意,如 1, 2,3 和 2,5,10 这样的测试用例并不能确保“是”的答案,因为具备这 样边长的三角形不存在。) 2. 是否有这样的测试用例,代表一个有效的等边三角形? 3. 是否有这样的测试用例,代表一个有效的等腰三角形?(注意如 2,2,4 的测试用例无效,因为这不是一个有效的三角形。) 4. 是否能少有三个这样的测试用例,代表有效的等腰三角形,从而可以测试 到两等边的所有三种可能情况?(如 3,3,4;3,4,3;4,3,3) 5. 是否有这样的测试用例,某边的长度等于 0? 6. 是否有这样的测试用例,某边的长度为负数? 7. 是否有这样的测试用例,三个整数皆大于 0,其中两个整数之和等于第三 个?(也就是说,如果程序判断 l,2,3 表示一个不规则二角形,它可能 就包含一个缺陷。) 8. 是否至少有三个第 7 类的测试用例,列举了一边等于另外两边之和的全部 可能情况(如 1,2,3;1,3,2;3,1,2)? 9. 是否有这样的测试用例,三个整数皆大于 0,其中两个整数之和小于第三 个整数?(如 1,2,4;12,15,30) 10. 是否至少有三个第 9 类的测试用例,列举了一边大于另外两边之和的全 部可能情况?(如 1,2,4;1,4,2;4,1,2) 11. 是否有这样的测试用例,三边长度皆为 0(0,0,0)? 12. 是否至少有一个这样的测试用例,输入的边长为非整数值(如 2.5,3.5, 5.5) 13. 是否至少有一个这样的测试用例,输入的边长个数不对(如仅输入了两 软件测试的艺术 未经同意,严禁以任何形式拷贝 3 个而不是三个整数)? 14. 对于每一个测试用例,除了定义输入值之外,是否定义了程序针对该输 入值的预期输出值? 当然,测试用例集即使满足了上述条件,也不能确保能查找出所有可能的错误。 但是,由于问题 1 至问题 13 代表了该程序不同版本中已经实际出现的错误,对该 程序进行的充分测试至少应该能够暴露这些错误。 开始关注自己的得分之前,请考虑以下情况:以我们的经验来看,高水平的专 业程序员平均得分仅 7.8(满分 14)。如果读者的得分更高,那么祝贺你。如果没有 那么高,我们将尽力帮助你。 这个测验说明,即使测试这样一个小的程序,也不是件容易的事。如果确实是 这样,那么想象一下测试一个十万行代码的空中交通管制系统、一个编译器,甚至 一个普通的工资管理程序的难度。随着面向对象编程语言(如 Java、C++)的出现, 测试也变得更加困难。举例来说,为测试这些语言开发出来的应用程序,测试用例 必须要找出与对象实例或内存管理有关的错误。 从上面这个例子来看,完全地测试一个复杂的、实际运行的程序似乎是不太可 能的。情况并非如此!尽管充分测试的难度令人望而生畏,但这是软件开发中一项 非常必需的任务,也是可以实现的一部分工作,通过本书我们可以认识到这一点。 第 2 章 软件测试的心理学和经济学 未经同意,严禁以任何形式拷贝 4 第 2 章 软件测试的心理学和经济学 软件测试是一项技术性工作,但同时也涉及经济学和人类心理学的一些重要因 素。 在理想情况下,我们会测试程序的所有可能执行情况。然而,在大多数情况下, 这几乎是不可能的,即使一个看起来非常简单的程序,其可能的输入与输出组合可 达到数百种甚至数千种,对所有的可能情况都设计测试用例是不切合实际的。对一 个复杂的应用程序进行完全的测试,将耗费大最的时间和人力资源,以至于在经济 上是不可行的。 另外,要成功地测试一个软件应用程序,测试人员也需要有正确的态度(也许 用“愿景(vision)”这个词会更好一些)。在某些情况下,测试人员的态度可能比实 际的测试过程本身还要重要。因此,在深入探讨软件测试更加技术化的本质之前, 我们先探讨一下软件测试的心理学和经济学问题。 2.1 软件测试的心理学 测试执行得差,其中一个主要原因在于大多数的程序员一开始就把“测试”这 个术语的定义搞错了,他们可能会认为: • “软件测试就是证明软件不存在错误的过程。” • “软件测试的目的在于证明软件能够正确完成其预定的功能。” • “软件测试就是建立一个‘软件做了其应该做的’信心的过程。” 这些定义都是本末倒置的。 每当测试一个程序时,总是想为程序增加一些价值。通过测试来增加程序的价 值,是指测试提高了程序的可靠性或质量。提高了程序的可靠性,是指找出并最终 修改了程序的错误。因此不要只是为了证明程序能够正确运行而去测试程序;相反, 应该一开始就假设程序中隐藏着错误(这种假设对于几乎所有的程序都成立),然 后测试程序,发现尽可能多的错误。 那么,对于测试,更为合适的定义应该是: Administrator 高亮 Administrator 高亮 Administrator 高亮 Administrator 高亮 Administrator 高亮 Administrator 高亮 软件测试的艺术 未经同意,严禁以任何形式拷贝 5 “测试是为发现错误而执行程序的过程”。 虽然这看起来像是个微妙的文字游戏,但确实有重要的区别。理解软件测试的 真正定义,会对成功地进行软件测试有很大的影响。 人类行为总是倾向于具有高度目标性,确立一个正确的目标有着重要的心理学 影响。如果我们的目的是证明程序中不存在错误,那就会在潜意识中倾向于实现这 个目标,也就是说,我们会倾向于选择可能较少导致程序失效的测试数据。另一方 面,如果我们的目标在于证明程序中存在错误,我们设计的测试数据就有可能更多 地发现间题。与前一种方法相比,后一种方法会更多地增加程序的价值。 这种对软件测试的定义,包含着无穷的内蕴,其中的很多都蕴涵在本书各处。 举例来说,它暗示了软件测试是一个破坏性的过程,甚至是一个“施虐”的过程, 达就说明为什么人多数人都觉得它困难。这种定义可能是违反我们愿望的,所幸的 是,我们大多数人总是对生活充满建设性而不是破坏性的愿景。大多数人都本能地 倾向于创造事物,而不是将事物破坏。这个定义还暗示了对于一个特定的程序:应 该如何设计测试用例(测试数据)、哪些人应该而哪些人又不应该执行测试。 为增进对软件测试正确定义的理解,另一条途径是分析一下对“成功的”和“不 成功的”这两个词的使用,当项目经理在归纳测试用例的结果时,尤其会用到这两 个词。大多数的项日经理将没发现错误的测试用例称为一次“成功的测试”,而将 发现了某个新错误的测试称为“不成功的测试”。 这又是一次本末倒置。“不成功的”表示事情不遂人意或令人失望。我们认为, 如果在测试某段程序时发现了错误,而且这些错误是可以修复的,就将这次合理设 计并得到有效执行的测试称作是“成功的”。如果本次测试可以最终确定再无其他 可查出的错误,同样也被称作是“成功的”。所谓“不成功的”测试,仅指未能适 当地对程序进行检查,在大多数情况下,未能找出错误的测试被认为是“不成功的”, 这是因为认为软件中不包含错误的观点基本上是不切实际的。 能发现新错误的测试用例不太可能被认为是“不成功的”;相反,能发现错误 就证明它是值得设计的。一个“不成功的”测试用例.会使程序输出正确的结果, 但不能发现任何错误。 Administrator 高亮 第 2 章 软件测试的心理学和经济学 未经同意,严禁以任何形式拷贝 6 我们可以类比一下病人看医生的情况,病人因为身体不舒服而去看医生。如果 医生对病人进行了某些实验检测,却没有诊断出任何病因,我们就不会认为这此实 验检测是“成功的”。之所以是“不成功的”检侧,是因为病人支付了昂贵的实验 检测费用,而病状却依然如故。病人会因此而质疑医生的诊断能力。但是,如果实 验检测诊断出病人是胃溃疡,那么这次检测就是“成功的”,医生可以开始进行适 当的治疗。因此.医疗行业会使用“成功的”或“不成功的”来表达适当的意思。 我们当然可以类推到软件测试中来,当我们开始测试某个程序时,它就好似我们的 病人。 “软件测试就是证明软件不存在错误的过程”,这个定义会带来第二个问题。 对于几乎所有的程序而言,甚至是非常小的程序,这个目标实际上也是无法达到的。 另外,心理学研究表明,当人们开始一项工作时,如果已经知道它是不可行的 或无法实现时,人的表现就会相当糟糕。举例来说,如果要求人们在 15 分钟之内 完成星期日《纽约时报》里的纵横填字游戏,那么我们会观察到 l0 分钟之后的进展 非常小,因为大多数人都会却步于这个现实,即这个任务似乎是不可能完成的。但 是如果要求在四个小时之内完成填字游戏,我们很可能有理由期望在最初 10 分钟 之内的进展会比前一种情况下的大。将软件测试定义为发现程序错误的过程,使得 测试是个可以完成的任务,从而克服了这个心理障碍。 诸如“软件测试就是证明‘软件做了其应该做的’的过程”此类的定义所带来 的第三个问题是,程序即使能够完成预定的功能,也仍然可能隐藏错误。也就是说, 当程序没有实现预期功能时,错误是清晰地显现出来的;如果程序做了其不应该做 的,这同样是一个错误;考虑一下第 l 章中的三角形测试程序。即使我们证明了程 序能够正确识别出不规则三角形、等腰三角形和等边三角形,但是在完成了不应执 行的任务后(例如将 1,2,3 说成是一个不规则三角形或将 0,0,0 说成是一个等 边三角形),程序仍然是错的。如果我们将软件测试视作发现错误的过程,而不是 将其视为证明“软件做了其应该做的”的过程,我们发现后一类错误的可能性会大 很多。 总结一下,软件测试更适合被视为试图发现程序中错误(假设其存在)的破坏 性的过程。一个成功的测试用例,通过诱发程序发生错误,可以在这个方向上促进 Administrator 高亮 软件测试的艺术 未经同意,严禁以任何形式拷贝 7 软件质量的改进。当然,最终我们还是要通过软件测试来建立某种程度的信心:软 件做了其应该做的,未做其不应该做的。但是通过对错误的不断研究是实现这个目 的的最佳途径。 有人可能会声称“本人的程序完美无缺”(不存在错误),针对这种情况建立起 信心的最好办法就是尽量反驳他,即努力发现不完美之处,而不只是确认程序在某 些输入情况下能够正确地工作。 2.2 软件测试的经济学 给出了软件测试的适当定义之后,下一步就是确定软件测试是否能够发现“所 有”的错误。我们将证明答案是否定的,即使是规模很小的程序。一般说来,要发 现程序中的所有错误也是不切实际的,常常也是不可能的。这个基本的问题反过来 暗示出软件测试的经济学问题、测试人员对被测软件的期望,以及测试用例的设计 方式。 为了应对测试经济学的挑战,应该在开始测试之前建立某些策略。黑盒测试和 白盒测试是两种最普遍的策略,我们将在下面两节中讨论。 2.2.1 黑盒测试 黑盒测试是一种重要的测试策略,又称为数据驱动的测试或输入/输出驱动的测 试。使用这种测试方法时,将程序视为一个黑盒子。测试目标与程序的内部机制和 结构完全无关,而是将重点集中放在发现程序不按其规范正确运行的环境条件。 在这种方法中,测试数据完全来源于软件规范(换句话说,不需要去了解程序 的内部结构)。如果想用这种方法来发现程序的所有错误,判定的标准就是“穷举 输入测试”,将所有可能的输入条件都作为测试用例。为什么这样做?比如说在三 角形测试的程序中,试过了三个等边三角形的测试用例。这不能确保正确地判断出 所有的等边三角形。程序中可能包含对边长为 3842,3842,3842 的特殊检查,并 指出此三角形为不规则三角形。由于程序是个黑盒子,因此能够确定此条语句存在 的惟一方法,就是试验所有的输入情况。 要穷举测试这个三角形程序,可能需要为所有有效的三角形创建测试用例,只 Administrator 高亮 Administrator 高亮 Administrator 高亮 Administrator 高亮 第 2 章 软件测试的心理学和经济学 未经同意,严禁以任何形式拷贝 8 要三角形边长在开发语言允许的最大整数值范围内。这些测试用例本身就是天文数 字,但这还决不是所谓穷尽的,当程序指出-3,4,5 是一个不规则三角形或 2,A, 2 是一个等腰三角形时,问题就暴露出来了,为了确保能够发现所有这样的错误, 不仅得用所有有效的输入,而且还得用所有可能的输入进行测试。因此,为了穷举 测试三角形程序,实际上需要创建无限的测试用例:这当然是不可能的。 如果测试这个三角形程序都这么难的话,那么要穷举测试一个稍大些的程序的 难度就更大了,设想一下,如果要对一个 C++编译器进行黑盒穷举测试,不仅要创 建代表所有有效 C++程序的测试用例(实际上,这又是个无穷数),还需要创建代 表所有无效 C++程序的测试用例(无穷数),以确保编译器能够检测出它们是无效 的。也就是说,编译器必须进行测试,确保其不会执行不应执行的操作——如顺利 地编译成功一个语法上不正确的程序。 如果程序使用到数据存储,如操作系统或数据库应用程序,这个问题会变得尤 为严重。举例来说,在航班预定系统这样的数据库应用程序中,诸如数据库查询、 航班预约这样的事务处理需要随上次事务的执行情况而定,因此,不仅要测试所有 有效的和无效的事务处理,还要测试所有可能的事务处理顺序。 上述讨论说明,穷举输入测试是无法实现的,这有两方面的含义,一是我们无 法测试一个程序以确保它是无错的,二是软件测试中需要考虑的一个基本问题是软 件测试的经济学。也就是说,由于穷举测试是不可能的,测试投人的目标在于通过 有限的测试用例,最大限度地提高发现的问题的数量,以取得最好的测试效果。除 了其他因素之外,要实现这个目标,还需要能够窥见软件的内部,对程序作些合理 但非无懈可击的假设(例如,如果三角形程序将 2,2,2 视为等边三角形,那就有 理由认为程序对 3,3,3 也作同样判断)。这种思路将形成本书第 4 章中测试用例 设计策略的部分方法。 2.2.2 白盒测试 另一种测试策略称为白盒测试或称逻辑驱动的测试,允许我们检查程序的内部 结构。这种测试策略对程序的逻辑结构迸行检查,从中获取测试数据(遗憾的是, 常常忽略了程序的规范)。 Administrator 高亮 软件测试的艺术 未经同意,严禁以任何形式拷贝 9 在这里我们的目标是针对达种测试策略,建立起与黑盒测试中穷举输入测试相 似的测试方法。也许有一个解决的办法,即将程序中的每条语句至少执行一次。但 是我们不难证明,这还是远远不够的。这种方法通常称为穷举路径测试,在本书第 4 章中将进一步进行深入探讨,在这里就不多加叙述。所谓穷举路径测试,即如果 使用测试用例执行了程序中所有可能的控制流路径,那么程序有可能得到了完全测 试。 然而,这个论断存在两个问题。首先,程序中不同逻辑路径的数最可能达到天 文数字。图 2-1 所示的小程序显示了这一点。该图是一个控制流图,每一个结点或 圆圈都代表一个按顺序执行的语句段,通常以一个分支语句结束。每一条边或弧线 表示语句段之间的控制(分支)的转换。图 2-1 描述的是一个有着 10~20 行语句的 程序,包含一个迭代 20 次的 DO 循环。在 DO 循环体中,包含一系列嵌套的 IF 语 句。要确定不同逻辑路径的数量,也相当于要确定从点 a~点 b 之间所有不同路径的 数量(假定程序中所有的判断语句都是相互独立的)。这个数量大约是 1014,即 100 万亿,是从 520+519… 十 51 计算而来,5 是循环体内的路径数量。由于大多数的人 难以对这个数字有一个直观的概念,不妨设想一下:如果在每五分钟内可以编写、 执行和确认一个测试用例,那么需要大约 10 亿年才能测试完所有的路径。假如可 以快上 300 倍,每秒就完成一次测试,也得用漫长的 320 万年才能完成这项工作。 第 2 章 软件测试的心理学和经济学 未经同意,严禁以任何形式拷贝 10 图 2-1 一个小型程序的控制流图 当然,在实际程序中,判断并非都是彼此独立的,这意味着可能实际执行的路 径数量要稍微少一些。但是,从另一方面来讲,实际应用的程序要比图 2-1 所描述 的简单程序复杂得多。因此,穷举路径测试就如同穷举输入测试,非但不可能,也 是不切实际的。 “穷举路径测试即完全的测试”论断存在的第二个问题是,虽然我们可以测试 到程序中的所有路径,但是程序可能仍然存在着错误。这有三个原因。 第一,即使是穷举路径测试也决不能保证程序符合其设计规范。举例来说,如 果要编写一个升序排序程序,但却错误地编成了一个降序排序程序,那么穷举路径 测试就没多大价值了;程序仍然存在着一个缺陷:它是个错误的程序因为不符合设 计的规范。 第二,程序可能会因为缺少某些路径而存在问题。穷举路径测试当然不能发现 缺少了哪些必需路径。 软件测试的艺术 未经同意,严禁以任何形式拷贝 11 第三,穷举路径测试可能不会暴露数据敏感错误。这样的例子有很多,举一个 简单的例子就能说明问题。假设在某个程序中要比较两个数值是否收敛,也就是检 查两个数值之间的差异是否小于某个既定的值。比如,我们可能会这样编一条 Java 语言的 IF 语句: if (a – b < c) System.Out.println(“a-b<c”); 当然,这条语句包含一个错误,因为它可能将 c 与 a-b 的绝对值进行比较。 然而,要找出这样的错误,取决于 a 和 b 所取的值,而仅仅执行程序中的每条路 径并不一定能找出错误来。 总之,尽管穷举输入测试要强于穷举路径测试,但两者都不是有效的方法,因 为这两种方法都不可行。那么,也许存在别的方法,将黑盒测试和白盒测试的要素 结合起来,形成一个合理但并不十分完美的测试策略。本书的第 4 章将深入讨论这 个话题。 2.3 软件测试的原则 让我们继续本章的话题基础,即软件测试中大多数重要的问题都是心理学问 题。我们可以归纳出一系列重要的测试指导原则,这些原则看上去大多都是显而易 见的,但常常总是被我们忽视掉。表 2-l 总结了这些重要原则,每条原则都将在下 面的章节中详细介绍。 表 2-1 软件测试的重要原则 编号 原则 1 测试用例中一个必需部分是对预期输出或结果进行定义 2 程序员应避免测试自己编写的程序 3 编写软件的组织不应当测试自已编写的软件 4 应当彻底检查每个测试的执行结果 5 测试用例的编写不仅应当根据有效和预料到的输入情况,而且也应当根据无效 和未预料到的输入情况 6 检查程序是否“未做其应该做的”仅是测试的一半,测试的另一半是检查程是 否“做了其不应该做的” 7 应避免测试用例用后即弃,除非软件本身就是个一次性的软件 8 计划测试工作时不应默许假定不会发现错误 9 程序某部分存在更多错误的可能性,与该部分已发现错误的数量成正比 10 软件测试是一项极富创造性,极具智力的挑战性的工作 Administrator 高亮 Administrator 高亮 第 2 章 软件测试的心理学和经济学 未经同意,严禁以任何形式拷贝 12 原则 l:测试用例中一个必需部分是对预期输出或结果的定义。 这条显而易见的原则在软件测试中是最常犯的错误之一。同样,这个问题也是 基于人们的心理的。如果某个测试用例的预期结果事先没有得到定义,由于“所见 即所想”现象的存在。某个似是而非、实际上是错误的结果可能会被解释成正确的 结论。换句话说,尽管“软件测试是破坏性”的定义是合理的,但人们在潜意识中 仍然渴望看到正确的结果。克服这种倾向的一种方法、就是通过事先精确定义程序 的预期输出,鼓励人们对所有的输出进行仔细检查。因此,一个测试用例必须包括 两个部分: 1.对程序的输入数据的描述。 2.对程序在上述输入数据下的正确输出结果的精确描述。 所谓“问题”,可以归纳为一个或一组我们不能给出可信服的解释、看上去不 太正常或不符合我们期望或预想的事实。应当明确的是,在确定事物存在“问题” 之前,人们必须已经形成特定的认识。没有期望,也就没有所谓的意外。 原则 2:程序员应当避免测试自己编写的程序. 任何作者都知道或应该知道,亲自编辑或校对自己的作品确实是个不好的做 法。作者清楚某段文字要说明的是什么,实际表达出来的意思却南辕北辙,而自己 可能却意识不到。况且实际上也不会想在自己的作品中找出什么错误来。对程序员 而言,也存在相同的问题。 如果我们对软件项目关注的重点发生变化,就会产生另外一个问题。当程序员 “建设性”地设计和编写完程序之后,很难让他突然改变视角以一种“破坏性”的 眼光来审查程序。正如许多房屋业主都知道的那样,撕下屋里的墙纸(这是个破坏 性的过程)并不容易,如果这些墙纸又恰恰是业主第一个亲手贴的,尤其令其沮丧 不已。同样,大多数程序员都不能有效地测试自己编写的程序,因为他们无法改变 思维方式来尽力暴露自己程序中的错误。另外,程序员可能会下意识地避免找出错 误来,担心受到同事、上司、客户或正在开发的程序或系统的主管的惩罚。 仅次于上面的心理学问题,还有一个重要的问题:由干程序员错误地理解了疑 难定义或规范,导致程序中存在错误。如果情况是这样,程序员可能会带着同样的 Administrator 高亮 Administrator 高亮 软件测试的艺术 未经同意,严禁以任何形式拷贝 13 误解来测试自己的程序。 这并不意味着程序员测试自己的程序是不可能的。当然,我们的言下之意是, 让其他人来测试程序会更加有效,也会更容易测试成功。 请注意,我们的论据并不适合于“调试”(纠正已知的错误)。“调试”由程序 的编写人员来完成会有效得多。 原则 3:编写软件的组织不应当测试自己编写的软件. 这里的论据与前面的论据相似。从很多方面来讲,一个软件项目或编程组织是 一个有机的机构,具有与个体程序员相似的心理问题。而且在大多数情况下,主要 是根据其在给定时间、特定成本范围内开发软件的能力来衡量编程组织或项目经 理。其中的一个原因是,度量时间和成本目标比较容易,而定量地衡量软件的可靠 性则极其困难.即便是合理规划和实施的测试过程,也可能被认为降低了完成进度 和成本目标的可能性,因此、编程组织难以客观地测试自己的软件。 同样,我们并不是说编程组织发现程序中的问题是不可能的,事实上很多组织 已经在某种程度上成功地做到了这一点。当然,我们的言下之意是,更经济的方法 是由客观、独立的第三方来进行测试。 原则 4:应当彻底检查每个测试的执行结果。 这个原则可能是最显而易见的原则,但也同样常常被忽视。我们见过大量的例 子,即便错误的症状在输出清单中可以清楚地看到,但还是没有找出那些错误来。 换言之,在后续测试中发现的错误,往往是前面的测试遗漏掉的。 原则 5:测试用例的编写不仅应当根据有效和预期的输入情况,而且也应当根据无 效和未预料到的输入情况。 在测试软件时,有一个自然的倾向,即将重点集中在有效和预期的输入情况上, 而忽略了无效和未预料到的情况。比如,在本书第 l 章三角形程序的测试中,总是 出现这个倾向。 例如,很少有人会向程序输入 1,2,5 以证明程序不会错误地将其解释为一个 不规则三角形,而不是一个无效三角形。此外,在软件产品中突然暴露出来的许多 Administrator 高亮 Administrator 高亮 Administrator 高亮 第 2 章 软件测试的心理学和经济学 未经同意,严禁以任何形式拷贝 14 问题是当程序以某些新的或未预料到的方式运行时发现的。因此,针对未预料到的 和无效输入情况的测试用例,似乎比针对有效输入情况的那些用例更能发现问题。 原则 6:检查程序是否“未做其应该做的”仅是测试的一半,测试的另一半是检查 程序是否“做了其不应该做的”。 这条原则是上条原则的必然结果。必须检查程序是否有我们不希望的负作用。 比如,某个工资管理程序即便可以生成正确的工资单,但是如果也为非雇员生成工 资单或者它覆盖掉了人员文件的第一条记录,这样的程序仍然是不正确的程序。 原则 7:应避免测试用例用后即弃,除非软件本身就是一个一次性的软件。 这个问题在采用交互式系统来测试软件时最常见。人们通常会坐在终端前,匆 忙地编写测试用例,然后将这些用例交由程序执行。这样做的问题在于,饱含我们 宝贵投人的测试用例,在测试结束后就消失了,一旦软件需要重新测试(例如,当 改正了某个错误或作了某种改进后),又必须重新设计这些测试用例。情况往往是 这样的,由于重新设计测试用例需要投人大量的工作,人们总是避免这样做。因此, 对该程序的重新测试极少会同上次一样严格。这就意味着,如果对程序的更改导致 了程序某个先前可以执行的部分发生了故障,这个故障往往是不会被发现的,保留 测试用例,当程序其他部件发生更动后重新执行,这就是我们所谓的“回归测试”。 原则 8:计划测试工作时不应默许假定不会发现错误。 项目经理经常容易犯这个错误,这也是使用了不正确的测试定义的一个迹象— —也就是说,假定“测试是一个证明程序正确运行的过程”。我们再一次重申,所 谓测试,就是为发现错误而执行程序的过程。 原则 9:程序某部分存在更多错误的可能性,与该部分已发现错误的数目成正比。 这种现象如图 2-2 所示。乍看上去,这幅图似乎没有什么意义,但很多程序都 存在这种现象。例如,假如某个程序由两个模块、类或子程序 A 和 B 组成,模块 A 中已经发现了五个错误,而模块 B 中仅仅找到了一处错误。如果模块 A 所经过 的测试并不是故意设计得更为严格,那么该原则告诉我们,模块 A 与模块 B 相比, 存在更多错误的可能性要大。 Administrator 高亮 Administrator 高亮 Administrator 高亮 Administrator 高亮 软件测试的艺术 未经同意,严禁以任何形式拷贝 15 该原则的另一个说法是,错误总是倾向于聚集存在,而在一个具体的程序中, 某些部分要比其他部分更容易存在错误,尽管没有人能够对这种现象给出很好的解 释。这种现象之所以有用.是因为它给予了我们对软件测试过程的洞察或反馈。如 果一个程序的某个部分远比其他部分更容易产生错误.那么这种现象告诉我们,为 了使测试获得更大的成效,最好对这些容易存在错误的部分进行额外的测试。 图 2-2 残存错误与已知错误间令人惊奇的联系 原则 10:软件测试是一项极富创造性、极具智力挑战性的工作。 测试一个大型软件所需要的创造性很可能超过了开发该软件所需要的创造 性.我们已经看到,要充分地测试一个软件以确保所有错误都不存在是不可能的。 本书后续章节讨论的技术使我们能够为某个软件设计出合理的测试用例集,然而这 些技术仍然需要大量的创造性。 2.4 小结 在阅读本书接下来的内容时,请牢记以下三个重要的测试原则: • 软件测试是为发现错误而执行程序的过程。 • 一个好的测试用例具有较高的发现某个尚未发现的错误的可能性。 • 一个成功的测试用例能够发现某个尚未发现的错误。

该用户的其他资料

  • 名称/格式
  • 评分
  • 下载次数
  • 资料大小
  • 上传时间

用户评论

0/200
    暂无评论
上传我的资料

相关资料

资料评价:

/ 149
所需积分:0 立即下载
返回
顶部
举报
资料
关闭

温馨提示

感谢您对爱问共享资料的支持,精彩活动将尽快为您呈现,敬请期待!