• 1. 第九章 软件测试
  • 2. 软件测试背景软件是人编的—所以不完美 实例: 1994-1995,迪斯尼的狮子王系统不支持问题 1999年12月3日,美国航天局火星极地登陆飞船失踪 1991年爱国者导弹防御系统系统时钟错误积累造成跟踪系统失去精确度 千年虫,世界各地解决2000年错误超过数亿美元
  • 3. 软件生存期各阶段间需保持的正确性用户要求用户: 我要什么?运行结果计算机: 程序运行得 到的结果源程序程序员: 我要让计算 机什么做?设计说明书设计员: 我要让软件 做什么?需求说明书分析员: 我可以提 供什么?12345理解正确性 表达正确性理解正确性 设计正确性 表达正确性理解正确性 编码正确性运行正确性 输入正确性相符吗?
  • 4. 教学内容: §9.1 测试的基本概念§9.2 黑盒测试§9.3 白盒测试 §9.4 测试用例设计 §9.5 软件的纠错§9.6多模块程序的测试策略§9.7 面向对象系统的测试
  • 5. 教学目的及要求: 要求: 掌握黑盒测试方法和测试用例的设计; 掌握白盒测试方法和测试用例的设计; 掌握单元测试方法和集成测试方法; 了解面向对象的软件测试方法。 目的: 主要讨论软件的测试,重点放在测试的策略与技术,纠错的策略与技术,以及多模块的测试内容与方法。
  • 6. §9.1 测试的基本概念 1. 目的与任务 2. 测试的原则 4. 测试的种类 3. 测试的特性 5. 测试的文档
  • 7. “测试的目的是说明程序正确地执行它应有的功能” 这种说法正确吗? 例9.1:程序Triangle,输入三个整数,表示一个三角形的三个边长,该程序产生一个结果,指出该三角形是等边三角形、等腰三角形还是不等边三角形。 为说明其能正确执行它的功能,可使用“测试 用例”(3,4,5),(5,5,6),(6,6,6), 程序都能给出正确结果,是否就可认为程序是正确的? 1.软件测试的目的与任务
  • 8. 软件测试的目的 基于不同的立场,存在着两种完全不同的测试目的。 从用户的角度出发,普遍希望通过软件测试暴露软件中隐藏的错误和缺陷,以考虑是否可接受该产品。 从软件开发者的角度出发,则希望测试成为表明软件产品中不存在错误的过程,验证该软件已正确地实现了用户的要求,确立人们对软件质量的信心。
  • 9. 测试的目的与地位 G.J.Myers在<软件测试技巧>中认为: 1.测试是为了寻找错误而运行程序的过程。 2.一个好的测试用例是指很可能找到迄今为止尚未 发现的错误的测试。 3.一个成功的测试是揭示了迄今为止尚未发现的错误 的测试。E.W.Dijkstra 指出: “程序测试能证明错误的存在,但不能证明错误不存在。”
  • 10. ※ 软件测试的目的与任务测试的目的:发现程序的错误; 任务:通过在计算机上执行程序,暴露程序中潜在的 错误。 纠错的目的:定位和纠正错误; 任务:消除软件故障,保证程序的可靠运行。
  • 11. 软件测试的定义: 软件测试是为了发现错误而执行程序的过程; 软件测试是根据软件开发个阶段的规格说明和程序的内部结构而精心设计一批测试用例(即输入数据及其预期的输出结果),并利用这些测试用例去运行程序,以发现程序错误的过程。
  • 12. 2.测试原则(9条) 应当把“尽早地和不断地进行软件测试”作为软件开发者的座右铭。 程序员应避免检查自己的程序。 pareto原则:测试发现的错误中80%很可能起源于20%的模块中。应孤立这些疑点模块重点测试。 测试用例应由输入数据和预期的输出结果两部分组成 程序修改后要回归测试 穷举测试是不可能的。
  • 13. 在设计测试用例时,应包括合理的输入条件和不合理的输入条件。充分注意测试中的群集现象。 经验表明,测试后程序中残存的错误数目与该程序中已发现的错误数目成正比。所有的测试都应追溯到用户需求 最严重的错误(从用户角度)是那些导致软件无法满足需求的错误。程序中的问题根源可能在开发前期的各阶段解决、纠正 错误也必须追溯到前期工作。 应长期保留测试用例,直至系统废弃。测试的原则
  • 14. 3. 测试的特性 挑剔性 “吹毛求疵” “鸡蛋里面头挑骨头” 复杂性 例如一个程序的功能是输入3个数作为三角形的3条边,然后鉴别这一三角形的类别。 不彻底性 例如有人开发了一个C语言的编译程序,要对他进行彻底的测试,需要设计多少个测试用例呢? 经济性
  • 15. 动态测试静态分析器分析代码评审白盒测试方法黑盒测试方法代码会审走查办公桌检查静态分析软件测试的 策略和方法 4.测试的种类
  • 16. 静态和动态测试汽车的检查过程: 踩油门 看车漆 打开前盖检查 发动汽车 听听发动机声音 上路行使静态测试动态测试
  • 17. 5.测试的文档测试计划 主体是“测试内容说明”它包括:测试项目的名称,各项测试的目的、步骤和进度,以及测试用例的设计等。 测试报告 主体是:“测试结果”,它包括测试项目名称,实测结果与期望结果的比较,发现的问题,以及测试达到的效果等。 测试用例={测试数据+期望结果}
  • 18. §9.2 黑盒测试 1. 等价分类法 3. 错误推测法 4. 因果图法 2. 边界值分析法
  • 19. 黑盒测试软件输入不深入代码细节的测试方法称为动态黑盒测试。 软件测试员充当客户来使用。输出这种方法是把测试对象看做一个黑盒子,测试人员完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明。
  • 20. 黑盒测试方法是在程序接口上进行测试,主要是为了发现以下错误: 是否有不正确或遗漏了的功能? 在接口上,输入能否正确地接受? 能否输出正确的结果? 是否有数据结构错误或外部信息(例如数据文件)访问错误? 性能上是否能够满足要求? 是否有初始化或终止性错误? 
  • 21. 例9.2 :假设一个程序P有输入量X和Y及输出量Z。在字长为32位的计算机上运行。若X、Y取整数,按黑盒方法进行穷举测试: 可能采用的 测试数据组: 232×232 =264 如果测试一组数据需要1毫秒,一年工作365× 24小时,完成所有测试需5亿年。 用黑盒测试发现程序中的错误,必须在所有可能的输入条件和输出条件中确定测试数据,来检查程序是否都能产生正确的输出。但这是不可能的。
  • 22. 1. 等价类划分法(Equivalence Partitioning) 把所有可能的输入数据(有效的和无效的)划分成若 干个等价的子集(称为等价类),使得每个子集中的 一个典型值在测试中的作用与这一子集中所有其它 值的作用相同,可从每个子集中选取一组数据来测 试程序。
  • 23. 例如,在程序的规格说明中,对输入条件有一句话: “…… 项数可以从1到999 ……” 则有效等价类是“1≤项数≤999” 两个无效等价类是“项数<1”或“项数>999”。在数轴上表示成:划分等价类的规则 5个(1)如果输入条件规定了取值范围,可定义一个有效等价 类和两个无效等价类。
  • 24. 例9.3:对招干考试系统“输入学生成绩”子模块设计测试用例 招干考试分三个专业,准考证号第一位为专业代号,如:1-行政专业,2-法律专业, 3-财经专业。 行政专业准考证号码为:110001~111215 法律专业准考证号码为:210001~212006 财经专业准考证号码为:310001~314015
  • 25. 例:准考证号码的等价类划分 有效等价类: (1) 110001 ~ 111215 (2) 210001 ~ 212006 (3) 310001 ~ 314015 无效等价类: (4) -  ~ 110000 (5) 111216 ~ 210000 (6) 212007 ~ 31000 (7) 314016 ~ + 
  • 26. (2) 如果输入条件规定了输入值的集合,或者是规定了“必须如何”的条件,这时可确立一个有效等价类和一个无效等价类。 例如,在Pascal语言中对变量标识符规定为“以字母打头的……串”。那么所有以字母打头的构成有效等价类,而不在此集合内(不以字母打头)的归于无效等价类。 (3) 如果输入条件是一个布尔量,则可以确定一个有效等价类和一个无效等价类。划分等价类的规则
  • 27. (4) 如果规定了输入数据的一组值,而且程序要对每个输入值分别进行处理。这时可为 每一个输入值确立一个有效等价类,此外针对这组值确立一个无效等价类,它是所有不允许的输入值的集合。 例如,在教师上岗方案中规定对教授、副教授、讲师和助教分别计算分数,做相应的处理。因此可以确定4个有效等价类为教授、副教授、讲师和助教,一个无效等价类,它是所有不符合以上身分的人员的输入值的集合。 (5) 如果规定了输入数据必须遵守的规则,则可以确立一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则)。 例如,Pascal语言规定 “一个语句必须以分号‘;’结束”。这时,可以确定一个有效等价类 “以‘;’结束”,若干个无效等价类 “以‘:’结束”、“以‘,’结束”、“以‘ ’结束”、“以LF结束”等。划分等价类的规则
  • 28. 从划分出的等价类中按以下原则设计测试用例: 为每一个等价类规定一个唯一编号; 设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖的有效等价类,重复这一步,直到所有的有效等价类都被覆盖为止; 设计一个新的测试用例,使其仅覆盖一个尚未被覆盖的无效等价类,重复这一步,直到所有的无效等价类都被覆盖为止。
  • 29. 例:某报表处理系统要求用户输入处理报表的日期,日期限制在2001年1月至2005年12月,即系统只能对该段期间内的报表进行处理,如日期不在此范围内,则显示输入错误信息。系统日规定由年、月的6位数字字符组成,前四位代表年,后两位代表月。如何用等价类划分法设计测试用例, 来测试程序的日期检查功能?
  • 30. 步骤第一步:等价类划分 第二步:为有效等价类设计测试用例。(多个有效等价类可使用一个测试用例) 第三步:为每一个无效等价类设至少 设计一个测试用例
  • 31. 第一步:等价类划分输入等价类 有效等价类 无效等价类 报表日期的 类型及长度6位数字字符(1)有非数字字符 (4) 少于6个数字字符 (5) 多于6个数字字符 (6)年份范围在2001~2005 之间 (2)小于2001 (7) 大于2005 (8)月份范围在1~12之间(3)“报表日期”输入条件的等价类表小于1 (9) 大于12 (10)
  • 32. 第二步:为有效等价类设计测试用例对表中编号为1,2,3 的3个有效等价类用一个测试用例覆盖: 测试数据 期望结果 覆盖范围有效数据? 等价类(1)(2)(3) 输入有效
  • 33. 第三步:为每一个无效等价类设至少 设计一个测试用例 不能出现相同 的测试用例 测试数据 期望结果 覆盖范围001MAY等价类(4)输入无效20015等价类(5)输入无效2001005等价类(6)输入无效200005等价类(7)输入无效200805等价类(8)输入无效200100等价类(9)输入无效200113等价类(10)输入无效 本例的10个等价类至 少需要8个测试用例
  • 34. 2. 边界值分析法(Boundary Value Analysis)软件边界与悬崖很类似测试内点测试外点被测试 子域
  • 35. 边界值分析法边界值分析法是对等价类划分方法的补充。 人们从长期的测试工作经验得知,大量的错误是发生在输入或输出范围的边界上,而不是在输入范围的内部。因此针对各种边界情况设计测试用例,可以查出更多的错误。 所谓边界值分析,就是把测试的重点放在各个等价类的边界上,选取正好等于,刚刚大于,或刚刚小于边界的值做为测试数据,并据此设计出相应的测试用例。
  • 36. 比如,在做三角形计算时,要输入三角形的三个边长:A、B和C。 我们应注意到这三个数值应当满足 A>0、B>0、C>0、 A+B>C、A+C>B、B+C>A,才能构成三角形。但如果把六个不等式中的任何一个大于号“>”错写成大于等于号“≥”,那就不能构成三角形。问题恰出现在容易被疏忽的边界附近。
  • 37. 边界值分析法与等价类划分法区别 (1)等价分类法的测试数据是在各个等价类允许的值域内任意选取的,而边界值分析的测试数据必须在边界值附近选取。 (2)一般地说,用边界值分析法设计的测试用例比等价分类法的代表性更广,发现错误的能力也更强。但是对边界的分析与确定比较复杂,要求测试人员具有更多的经验和创造性。 (3)还需指出,有些包含的边界情况比较简单,只需要分析输入等价类。在有些情况下,除了考察输入值边界外,还需要考察输出值和其他可能存在的边界。
  • 38. 例:假定被测程序是一个计算x的正弦值sin(x),其输出具有3个边界值-1、0、1。在选择测试用例时,应使x的值分别产生上述的3种输出边界值,即选取-∏/2、0、∏/2作为x的测试数据。
  • 39. 3. 错误推测法(error guessing)人们也可以靠经验和直觉推测程序中可能存在的各种错误,从而有针对性地编写检查这些错误的例子。这就是错误推测法。 显然,它比前两种方法更多地依靠测试人员的直觉和经验。所以,一般都先用前两种方法设计测试用例,然后用猜错法补充一些例子作为辅助手段。根据经验来设计测试用例的方法 例如,数据测试中的: 缺省值 空白 空值 零值 无
  • 40. 错误推测法基本思想:列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据它们选择测试用例。 仍以上述的报表日期为例,在已经用等价分类法和边界值分析发设计过测试用例的基础上,还可用猜错法补充一些测试用例,例如: 报表日期为:“0” 漏送“报表日期” 年月次序颠倒,例如将“200112”误输为“122001”
  • 41. 4.因果图因果图的适用范围 如果在测试时必须考虑输入条件的各种组合,可使用一种适合于描述对于多种条件的组合,相应产生多个动作的形式来设计测试用例,这就需要利用因果图。 因果图方法最终生成的就是判定表。它适合于检查程序输入条件的各种组合情况。
  • 42. (1)分析软件规格说明描述中,哪些是原因 (即输入条件或输入条件的等价类),哪些是结果 (即输出条件),并给每个原因和结果赋予一个标识符。 (2)分析软件规格说明描述中的语义,找出原因与结果之间,原因与原因之间对应的是什么关系? 根据这些关系,画出因果图。 (3)由于语法或环境限制,有些原因与原因之间,原因与结果之间的组合情况不可能出现。为表明这些特殊情况,在因果图上用一些记号标明约束或限制条件。 (4)把因果图转换成判定表。 (5)把判定表的每一列拿出来作为依据,设计测试用例。 用因果图生成测试用例的基本步骤
  • 43. 在因果图中出现的基本符号 通常在因果图中用Ci表示原因,用Ei表示结果,各结点表示状态,可取值“0”或“1”。“0”表示某状态不出现,“1”表示某状态出现。 主要的原因和结果之间的关系有:
  • 44. 表示约束条件的符号 为了表示原因与原因之间,结果与结果之间可能存在的约束条件,在因果图中可以附加一些表示约束条件的符号。
  • 45. 例 :某电力公司有A、B、C、D四类收费标准, 并规定: 居民用电 <100度/月 按A类收费 ≥100度/月按B类收费 动力用电 <10000度/月,非高峰,B类收费 ≥10000度/月,非高峰,C类收费 <10000度/月, 高峰,C类收费 ≥10000度/月, 高峰,D类收费
  • 46. 设计测试用例的步骤1 列举所有存在的输入条件和输出结果。 2 根据输入条件和输出条件生成判定表。 3 针对判定表的每一列产生一个测试用例。
  • 47. 输入条件(原因) 输出动作(后果)1——居民用电 A ——按A类收费 2——动力用电 B ——按B类收费 3—— <100度/月 C ——按C类收费 4——<10000度/月 D ——按D类收费 5——高峰用电
  • 48. 把因果图转换为判定表组合条件条件 (原因) 动作 (结果)ABC123123456101100011000110000100001104101050011D000110010000测试用例
  • 49. 为判定表每一列设计一个测试用例:1列 居民电,90度/月 A 2列 居民电,110度/月 B 3列 动力电,非高峰,8000度/月 B 4列 动力电,非高峰,1.2万度/月 C 5列 动力电, 高峰,0.9万度/月 C 6列 动力电, 高峰,1.1万度/月 D 条件 测试用例 预期结果 组合 (输入数据) (输出动作)
  • 50. 例:有一个处理单价为5角钱的饮料的自动售货机软件测试用例的设计。其规格说明如下: 若投入5角钱或1元钱的硬币,押下〖橙汁〗或〖啤酒〗的按钮,则相应的饮料就送出来。若售货机没有零钱找,则一个显示〖零钱找完〗的红灯亮,这时在投入1元硬币并押下按钮后,饮料不送出来而且1元硬币也退出来;若有零钱找,则显示〖零钱找完〗的红灯灭,在送出饮料的同时退还5角硬币。”
  • 51. 分析这一段说明,列出原因和结果 原因: 1. 售货机有零钱找 2. 投入1元硬币 3. 投入5角硬币 4. 押下橙汁按钮 5. 押下啤酒按钮 建立中间结点,表示处理中间状态 11. 投入1元硬币且押下饮料按钮 12. 押下〖橙汁〗或〖啤酒〗的按钮 13. 应当找5角零钱并且售货机有零钱找 14. 钱已付清
  • 52. 结果: 21. 售货机〖零钱找完〗灯亮 22. 退还1元硬币 23. 退还5角硬币 24. 送出橙汁饮料 25. 送出啤酒饮料 (2) 画出因果图。所有原因结点列在左 边,所有结果结点列在右边。 (3) 由于 2 与 3 ,4 与 5 不能同时发生, 分别加上约束条件E。 (4) 因果图 (5) 转换成判定表
  • 53. (本页无文本内容)
  • 54. (本页无文本内容)
  • 55. §9.3 白盒测试 1. 逻辑覆盖测试法 2. 路径测试法
  • 56. 动态白盒测试 —带上X光眼镜测试软件??????????????3581322.293419985680302829734315250*(1+0.015)*((1+0.015)^360-1)/0.015250*(1+0.015)*((1+0.015)^360-1)/0.015假如知道一个盒子包含一台计算机,而另一个盒 子是人用纸笔计算,就会选择不同的测试用例。了解软件的运作方式会影响测试手段
  • 57. 测试方案:通常的做法是,用黑盒法设计基本的测试方案,再用白盒法补充一些方案。白盒法把测试对象看做一个透明的盒子,它允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试。 通过在不同点检查程序的状态,确定实际的状态是否与预期的状态一致。因此白盒测试又称为结构测试或逻辑驱动测试。
  • 58. 软件人员使用白盒测试方法,主要想对程序模块进行如下的检查: 对程序模块的所有独立的执行路径至少测试一 次; 对所有的逻辑判定,取“真”与取“假”的两种情况都至少测试一次; 在循环的边界和运行界限内执行循环体; 测试内部数据结构的有效性等。
  • 59. 白盒测试 不论是每个功能或每个逻辑控制通路,如果对所有的情况都进行测试,这样的测试成为穷尽测试。穷尽测试在一般情况下是实际不可行的。循环20次各种组合,约520种白盒测试例二:如右图,对每一条路径进 行测试需要1毫秒,假定一年工作 365 × 24小时,要想把所有路径 测试完,需3170年。
  • 60. 1. 逻辑覆盖法 (1)语句覆盖 (2)判定覆盖 (4)判定/条件覆盖 (3)条件覆盖 (5)条件组合覆盖(6)路径覆盖(7)点覆盖 (8)边覆盖 逻辑覆盖是以程序内部的逻辑结构为基础的设计测试 用例的技术。从覆盖源程序语句的详尽程度分析,大致有以 下不同的覆盖标准:
  • 61. (1)语句覆盖(A>1) and (B=0)(A=2) or (X>1)X = X / AX=X+1TTFFbcePROCEDURE Example(A,B:real; X:real ); Begin IF (A>1) AND (B=0) THEN X:= X / A; IF ( A=2 ) OR (X>1) THEN X:=X+1 END;a1Sd234567I. A=2, B= 0, X=4 ---- sacbed语句覆盖 所有的语句至少执行一次!
  • 62. 语句覆盖是最弱的逻辑覆盖! 语句覆盖对程序的逻辑覆盖很少,在上面例子中两个判定条件都只测试了条件为真的情况,如果条件为假时处理有错误,显然不能发现。 此外,语句覆盖只关心判定表达式的值,而没有分别测试判定表达式中每个条件取不同值的情况。如果程序中把第一个判定表达式中逻辑运算符“AND”错写成“OR”或误把第二个表达式的条件“X>1”误写成“X<1”使用上面的测试数据并不能查出这些错误。
  • 63. (2)判定覆盖(分支覆盖)(A>1) and (B=0)(A=2) or (X>1)X = X / AX=X+1TTFFbcea1Sd234567 不仅每个语句至少执行一次,而且每个判定的每种可能结果都至少执行一次! 即每个判定的每个分支都至少执行一次!I: A=3, B=0,X=3: sacbdII: A=2, B=1,X=1: sabed 判定覆盖比语句覆盖强!但是对程序逻辑的覆盖程度仍然不高,例如,上面的测试数据只覆盖了程序全部路径的一半。
  • 64. (3)条件覆盖(A>1) and (B=0)(A=2) or (X>1)X = X / AX=X+1TTFFbcea1Sd234567 每个语句至少执行一次,而且判定表达式中的每个条件都要取得各种可能的结果。(A>1)(A≤1)(B=0)(B≠0)(A=2)(A≠2)(X>1)(X≤1)II: A=1, B=1,X=1: sabd 条件覆盖一般情况下比判定覆盖要强,但是也有满足条件覆盖但不能满足判定覆盖的情况。I: A=2, B=0,X=4: sacbedI: A=2, B=0,X=1: sacbedII: A=1, B=1,X=1: sabed
  • 65. 第一判定表达式: 设条件 A>1 取真 记为 T1 假 T1 条件 B=1 取真 记为 T2 假 T2 第二判定表达式: 设条件 A=2 取真 记为 T3 假 T3 条件 X>1 取真 记为 T4 假 T4
  • 66. 条件覆盖 开始(A>1) AND (B=0)(A=2) OR (X>1)返回X=X/AX=X+1FFTTabdce满足条件: T1,T1, T2,T2 T3,T3 T4,T4
  • 67. 测试用例 通过 满足的 覆盖 A B X 路径 条件 分支 1 0 3 abe T1,T2,T3,T4 b,e 1 1 abe T1,T2,T3,T4 b,e 两个测试用例覆盖了四个条件八种可能取值。 未覆盖c、d分支,不满足判定覆盖的要求。 条件覆盖不一定包含判定覆盖 判定覆盖也不一定包含条件覆盖
  • 68. (4)判定/条件覆盖 选取足够多的测试用例,使判断中的每个条件的 所有可能取值至少执行一次,同时每个判断本身的所有 可能判断结果至少执行一次。 http://dongdong711005.blog.hexun.com/5397978_d.html
  • 69. 判定/条件覆盖(A>1) and (B=0)(A=2) or (X>1)X = X / AX=X+1TTFFbcea1234567Sd 判定条件不一定包含条件覆盖,条件覆盖也不一定包含判定覆盖;事实上同时满足这两种标准的判定/条件覆盖也不会比条件覆盖更强。(A>1)(A≤1)(B=0)(B≠0)(A=2)(A≠2)(X>1)(X≤1)II: A=1, B=1,X=1: sabdI: A=2, B=0,X=4: sacbed 测试用例I,II既满足判定覆盖也满足条件覆盖的要求。严格来讲,合适的条件覆盖测试用例设计应该作到满足判定/条件覆盖的标准:判定/条件覆盖并不比条件覆盖更强。
  • 70. 判定/条件 覆盖 开始(A>1) AND (B=0)(A=2) OR (X>1)返回X=X/AX=X+1FFTTabdce满足条件: T1,T1, T2,T2 T3,T3 T4,T4
  • 71. 测试用例 通过 满足的 覆盖 A B X 路径 条件 分支 2 0 4 ace T1,T2,T3,T4 c,e 2 1 1 abd T1,T2,T3,T4 b,d 能同时满足判定、条件两种覆盖标准。
  • 72. 测试用例 通过 满足的 覆盖 A B X 路径 条件 分支 2 0 3 ace T1,T2,T3,T4 c,e 2 1 1 abe T1,T2,T3,T4 b,e 1 0 3 abe T1,T2,T3,T4 b,e 1 1 1 abd T1,T2,T3,T4 b,d
  • 73. (5)条件组合覆盖(A>1) and (B=0)(A=2) or (X>1)X = X / AX=X+1TTFFba1234567Sd 条件组合覆盖要求选取足够多的测试数据,使得每个判定表达式中条件的各种可能组合都至少出现一次。(A>1)(A≤1)(B=0)(B≠0)(A=2)(A≠2)(X>1)(X≤1)I. A=2,B=0,X=4II. A=2,B=1,X=1III. A=1,B=0,X=2IV. A=1,B=1,X=1 满足条件组合覆盖标准的测试数据,也一定满足判定覆盖、条件覆盖和判定/条件覆盖标准。I: sacbed II: sabed III: sabed IV: sabd覆盖路径ce
  • 74. 条件组合覆盖 所有可能的条件取值组合至少执行一次 A>1, B=0 A>1, B≠0 A≯1, B=0 A≯1, B≠0 A=2, X>1 A=2, X≯1 A≠2, X>1 A≠2, X≯1
  • 75. 开始(A>1) AND (B=0)(A=2) OR (X>1)返回X=X/AX=X+1FFTTabdce
  • 76. 测试用例 通过 满足的 覆盖 A B X 路径 条件 分支 2 0 4 ace T1,T2,T3,T4 1,5 2 1 1 abe T1,T2,T3,T4 2,6 1 0 2 abd T1,T2,T3,T4 3,7 1 1 1 abd T1,T2,T3,T4 4,8 覆盖了所有判断的可取分支,路径漏掉了L4(acd),测试不完全。
  • 77. (6)路径覆盖: 选取足够多的测试数据,使程序的每条可能路径都至少执行一次(如果程序图中有环,则要求每个环至少经过一次)。 路径覆盖是较强的逻辑覆盖标准。I: A=1,B=1,X=1 (1-2-3) ; II: A=1,B=1,X=2 (1-2-6-7) III: A=3,B=0,X=1 (1-4-5-3); IV: A=2,B=0,X=4 (1-4-5-6-7)1234567
  • 78. 开始(A>1) AND (B=0)(A=2) OR (X>1)返回X=X/AX=X+1FFTTabdce
  • 79. 路径覆盖 覆盖每一个可能的路径 测试用例 通过 满足的 覆盖 A B X 路径 条件 分支 1 1 1 abd T1,T2,T3,T4 b,d 1 1 2 abe T1,T2,T3,T4 b,e 3 0 1 acd T1,T2,T3,T4 c,d 2 0 4 ace T1,T2,T3,T4 c,e
  • 80. (7)点覆盖: 如果连通图 G 的子图G´是连通的,而且包含G的所有节点,则称G´是G的点覆盖。 与语句覆盖标准相同。
  • 81. (8)边覆盖: 如果连通图 G 的子图G´是连通的,而且包含G的所有边,则称G´是G的边覆盖。 通常与判定覆盖标准相同。
  • 82. 2.路径测试法 逻辑覆盖测试引导人们把注意力集中在程序的各个判定部分,抓住了结构测试的重点。但是另一方面,它却忽略了另一个对测试也有重要影响的方面——程序的执行路径。 随着程序复杂性的增长和测试技术的发展,人们逐渐认识到这种忽略所带来的缺陷。
  • 83. 路径测试基本路径测试方法把覆盖的路径数压缩到一定限度内,程序中的循环体最多只执行一次。 它是在程序控制流图的基础上,分析控制构造的环路复杂性,导出基本可执行路径集合,设计测试用例的方法。设计出的测试用例要保证在测试中,程序的每一个可执行语句至少要执行一次。
  • 84. 程序图符号○为控制流图的一个结点,表示一个或多个无分支的PDL语句或源程序语句。箭头为边,表示控制流的方向。 顺序执行的多个节点,在程序图中可以合并画成一个节点。 边和结点圈定的区域叫做区域,当对区域计数时,图形外的区域也应记为一个区域。 如果判断中的条件表达式是由一个或多个逻辑运算符 (OR, AND, ...) 连接的复合条件表达式,则需改为一系列只有单个条件的嵌套的判断。
  • 85. 利用流图(flow graph )表示控制逻辑 顺序结构if 结构Case 结构while 结构until 结构
  • 86. (本页无文本内容)
  • 87. (本页无文本内容)
  • 88. 1762,38910114,5 76 231 8 4 511 910 程序图是对待测试程序过程处理的一种表示节点边区域区域:由边和解点封闭起来的区域 计算区域:不要忘记区域外的部分待测试程序用流图表示的待测试程序
  • 89. (本页无文本内容)
  • 90. 程序环路复杂性程序的环路复杂性给出了程序基本路径集中的独立路径条数,这是确保程序中每个可执行语句至少执行一次所必需的测试用例数目的上界。 从控制流图来看,一条独立路径是至少包含有一条在其它独立路径中从未有过的边的路径。
  • 91. 确定覆盖测试路径上界的计算(环复杂度计算)上面的例子得出: 基本的路径集并不是唯一的问题: 寻找多少条路径,就能够足够覆盖全部测试路径呢?环复杂度计算: 为确定测试路径的上界提供了依据
  • 92. 环复杂度计算法:三种方法之一: 1.流图的区域数量应该对应于环复杂度 2.给定流图G的环复杂度V(G)定义为:V(G)=E-N+2 其中:E为流图中的边数量,N为流图中的节点数量 3.给定流图G的环复杂度V(G)也可以定义为:V(G)=P+1 其中:P为流图中的判断节点数量
  • 93. 1762,38910114,5环复杂度计算法例子:1.程序图的区域数量 = 4 2.V(G)=11(条边)- 9(节点)+ 2 = 4 3.V(G)=3(判断节点)+ 1 = 4结论是: 4条路径足够覆盖全部测试路径。
  • 94. 根据流图标识独立路径 独立路径:至少沿一条新的边移动的路径1762,38910114,5路径1:1-11 路径2:1-2-3-4-5-10-1-11 路径3:1-2-3-6-8-9-10-1-11 路径4:1-2-3-6-7-9-10-1-11对以上路径的遍历,就是至少一次地执行了程序中的所有语句。
  • 95. 导出测试用例导出测试用例,确保基本路径集中的每一条路径的执行。 根据判断结点给出的条件,选择适当的数据以保证某一条路径可以被测试到 — 用逻辑覆盖方法。
  • 96. 每个测试用例执行之后,与预期结果进行比较。如果所有测试用例都执行完毕,则可以确信程序中所有的可执行语句至少被执行了一次。 必须注意,一些独立的路径(如例中的路径1),往往不是完全孤立的,有时它是程序正常的控制流的一部分,这时,这些路径的测试可以是另一条路径测试的一部分。
  • 97. 用基本路径法导出测试案例的步骤 PROCEDURE average INTERFACE RETURNS average,total.input,total.valid; INTERFACE ACCEPTS value,minimum,maximum; TYPE value[1:100] IS SCALAR ARRAY TYPE average,total.input,total.valid, minimum,maximum,sum IS SCALAR; TYPE i IS INTEGE; ..... END average声明部分处理部分接下页例:计算<100个数的平均值,并计算和,以及参算总数
  • 98. i = 1; Total.input = total.valid = 0; ⑴ Sum = 0; DO WHILE value[i]<> -999 ⑵ AND total.input <100 ⑶ increment total.input by 1; ⑷ IF value[i] >= minimum ⑸ AND vale[i] <= maximum ⑹ THEN increment total.valid by 1; sum = sum + value[i]; ⑺ ELSE skip; ENDIF increment i by 1; ⑻ ENDDO ⑼ IF total.valid > 0 ⑽ THEN average = sum / total.valid; ⑾ ELSE average = -999; ⑿ ENDIF ⒀ 23456187910111213①以处理代码为基础,画流图处理部分
  • 99. ②确定流图的环复杂度average 流图 23456187910111213V(G)= 6个区域 V(G)=17边-13个节点 + 2 = 6 V(G)=5个判定节点 + 1 = 6
  • 100. ③确定线性独立路径的一个基本集average 流图 23456187910111213路径1:1-2-10-11-13 路径2:1-2-10-12-13 路径3:1-2-3-10-11-13 路径4:1-2-3-4-5-8-9-2... 路径5:1-2-3-4-5-6-8-9-2... 路径6:1-2-3-4-5-6-7-8-9-2...根据环复杂度计算,6条路径足够覆盖所有的测试路径。选取独立路径6条:
  • 101. ④准备测试案例,强制执行基本集中的每条路径准备路径1:1-2-10-11-13 测试案例: i = 1; Total.input = total.valid = 0; ⑴ Sum = 0; DO WHILE value[i]<> -999 ⑵ AND total.input <100 ⑶ increment total.input by 1; ⑷ IF vale[i] >= minimum ⑸ AND vale[i] <= maximum ⑹ THEN increment total.valid by 1; sum = sum + value[i]; ⑺ ELSE skip; ENDIF increment i by 1; ⑻ ENDDO ⑼ IF total.valid > 0 ⑽ THEN average = sum / total.valid; ⑾ ELSE average = -999; ⑿ ENDIF ⒀注意:满足(2)直接到(10)的条件是: value[i]==-999 或者 total.input >=100 但是,如果一次都没有执行 DO WHILE 则不会执行 (11),因为 total.valid == 0 ,所以路径1无法独立测试,需要结合其它路径的测试来完成路径1测试案例: value[k]=有效输入 value[i]=-999 (其中k
  • 102. ④准备测试案例,强制执行基本集中的每条路径准备路径2:1-2-10-12-13 测试案例: i = 1; Total.input = total.valid = 0; ⑴ Sum = 0; DO WHILE value[i]<> -999 ⑵ AND total.input <100 ⑶ increment total.input by 1; ⑷ IF vale[i] >= minimum ⑸ AND vale[i] <= maximum ⑹ THEN increment total.valid by 1; sum = sum + value[i]; ⑺ ELSE skip; ENDIF increment i by 1; ⑻ ENDDO ⑼ IF total.valid > 0 ⑽ THEN average = sum / total.valid; ⑾ ELSE average = -999; ⑿ ENDIF ⒀路径2测试案例: value[i]=-999 预期结果:平均值=-999
  • 103. ④准备测试案例,强制执行基本集中的每条路径准备路径3:1-2-3-10-11-13 测试案例: i = 1; Total.input = total.valid = 0; ⑴ Sum = 0; DO WHILE value[i]<> -999 ⑵ AND total.input <100 ⑶ increment total.input by 1; ⑷ IF vale[i] >= minimum ⑸ AND vale[i] <= maximum ⑹ THEN increment total.valid by 1; sum = sum + value[i]; ⑺ ELSE skip; ENDIF increment i by 1; ⑻ ENDDO ⑼ IF total.valid > 0 ⑽ THEN average = sum / total.valid; ⑾ ELSE average = -999; ⑿ ENDIF ⒀路径3测试案例: 前100个数值应该有效 预期结果:正确的100个数的平均值和总和测试多于100个值的情况
  • 104. ④准备测试案例,强制执行基本集中的每条路径准备路径4:1-2-3-4-5-8-9-2... 测试案例: i = 1; Total.input = total.valid = 0; ⑴ Sum = 0; DO WHILE value[i]<> -999 ⑵ AND total.input <100 ⑶ increment total.input by 1; ⑷ IF vale[i] >= minimum ⑸ AND vale[i] <= maximum ⑹ THEN increment total.valid by 1; sum = sum + value[i]; ⑺ ELSE skip; ENDIF increment i by 1; ⑻ ENDDO ⑼ IF total.valid > 0 ⑽ THEN average = sum / total.valid; ⑾ ELSE average = -999; ⑿ ENDIF ⒀路径4测试案例: value[k]=有效输入 (其中k<100) value[i] < 最小值 (其中i
  • 105. ④准备测试案例,强制执行基本集中的每条路径准备路径5:1-2-3-4-5-6-8-9-2... 测试案例: i = 1; Total.input = total.valid = 0; ⑴ Sum = 0; DO WHILE value[i]<> -999 ⑵ AND total.input <100 ⑶ increment total.input by 1; ⑷ IF vale[i] >= minimum ⑸ AND vale[i] <= maximum ⑹ THEN increment total.valid by 1; sum = sum + value[i]; ⑺ ELSE skip; ENDIF increment i by 1; ⑻ ENDDO ⑼ IF total.valid > 0 ⑽ THEN average = sum / total.valid; ⑾ ELSE average = -999; ⑿ ENDIF ⒀路径5测试案例: value[k]=有效输入 (其中k<100) value[i] > 最大值 (其中i
  • 106. ④准备测试案例,强制执行基本集中的每条路径准备路径6:1-2-3-4-5-6-7-8-9-2...测试案例: i = 1; Total.input = total.valid = 0; ⑴ Sum = 0; DO WHILE value[i]<> -999 ⑵ AND total.input <100 ⑶ increment total.input by 1; ⑷ IF vale[i] >= minimum ⑸ AND vale[i] <= maximum ⑹ THEN increment total.valid by 1; sum = sum + value[i]; ⑺ ELSE skip; ENDIF increment i by 1; ⑻ ENDDO ⑼ IF total.valid > 0 ⑽ THEN average = sum / total.valid; ⑾ ELSE average = -999; ⑿ ENDIF ⒀路径6测试案例: value[k]=有效输入 (其中k<100) 预期结果:基于k的正确平均值和总数
  • 107. 循环的类别:简单循环嵌套循环串接循环无结构循环
  • 108. 简单循环的测试案例选取策略:设:n为最大循环数 1)跳过整个循环 2)只有一次通过循环 3)两次通过循环 4)m次通过循环(m
  • 109. 嵌套循环的测试案例选取策略:如果采用简单测试的方法,将会使测试案例成几何级增长。所以采用: 1)从内层循环开始,将其它循环值设置为最小 2)对内层使用简单循环测试方法,并为范围外的值添加适当的测试 3)由内向外构造下一个循环测试,对已经测过的内层循环设为典型值 4)继续以上测试方式,直至全部嵌套循环结束嵌套循环
  • 110. 串接循环的测试案例选取策略:串接循环1)如果串接循环彼此独立,采用简单循环测试策略 2)如果多个循环的循环计数是串接方式的,采用嵌套循环的测试策略无结构循环: 应该重新设计循环结构,使之成为其它循环方式
  • 111. 黑盒测试与白盒测试优缺点比较黑盒测试 白盒测试 优 点缺 点性 质①适用于各阶段测试 ②从产品功能角度测试 ③容易入手生成测试数据①可构成测试数据使特定程 序部分得到测试 ②有一定的充分性度量手段 ③可或较多工具支持①某些代码得不到测试 ②如果规格说明有误, 则无法发现 ③不易进行充分性测试①不易生成测试数据(通常) ②无法对未实现规格说明的 部分进行测试 ③工作量大,通常只用于单 元测试,有应用局限是一种确认技术,回答 “我们在构造一个正确 的系统吗?” 是一种验证技术,回答 “我们在正确地构造一个系 统吗?”
  • 112. §9.4 测试用例设计 1. 黑盒测试用例设计 2. 白盒测试用例设计
  • 113. 例:程序Triangle读入三个整数值,这三个整数代 表同一个三角形三条边的长度,程序根据这三个值判断三角形属于不等边、等腰或等边三角形中的哪一种。Triangle三角形的类型?1. 黑盒测试用例设计abca,b,c
  • 114. 黑盒测试(等价类划分) 正常的三角形 (a,b,c)不等边三角形(8,10,12); (10,8,12); (10,12,8)等边三角形(10,10,10)等腰三角形(10,10,17); (10,17,10); (17,10,10) 不能构成三角形的非法数据 (a,b,c)a+b
  • 115. starta
  • 116. 2.白盒测试用例设计(P207)
  • 117. §9.5 软件的纠错1.纠错的措略 试凑法 跟踪法 推理法 2.常用的纠错技术 插入打印语句 设置断点 掩蔽部分程序 蛮力纠错技术 3.纠错举例
  • 118. §9.6多模块程序的测试策略1.测试的层次性
  • 119. 层次测试的信息流程被测 模块单元 测试设计 信息集成 测试被测 模块单元 测试被测 模块单元 测试测试过 的模块确认 测试系统 测试软件 需求其它系 统元素装配好的软件 确认 的软件可运 行的 软件
  • 120. 单元测试集成测试确认测试系统测试软件调试(排措过程 )软件测试步骤测试中常见的错误 单元测试规程自顶向下的测试 自底向上的测试 回归测试 烟雾测试深度优先 宽度优先测试 测试恢复测试 安全测试 应力测试 性能测试高阶测试蛮力法 回溯法 原因排除法
  • 121. 软件测试步骤单元测试 集成测试 高阶测试 需求分析设计编码测试方向单元测试:验证程序控制结构的分支,尽量覆盖所有可能的错误 集成测试:进一步验证程序以及测试程序构造问题 高阶测试:(确认测试)对已经确认的标准的测试
  • 122. 软件测试的策略测试过程按4个步骤进行,即单元测试、组装测试、确认测试和系统测试。 开始是单元测试,集中对用源代码实现的每一个程序单元进行测试,检查各个程序模块是否正确地实现了规定的功能。
  • 123. 组装测试把已测试过的模块组装起来,主要对与设计相关的软件体系结构的构造进行测试。 确认测试则是要检查已实现的软件是否满足了需求规格说明中确定了的各种需求,以及软件配置是否完全、正确。 系统测试把已经经过确认的软件纳入实际运行环境中,与其它系统成份组合在一起进行测试。
  • 124. 2.程序错误的类型语法错误 结构性错误 功能性错误 接口错误 I/O错误 数据结构错误 算法错误 比较及控制逻辑错误 错误处理错误
  • 125. ⑴优先级错误 ⑵混合模式的操作错误 ⑶初始化值的错误 ⑷精度不准确的错误 ⑸表达式符号的错误计算中的常见错误:比较控制转移的常见错误:⑴不同数据类型的比较 ⑵错误的逻辑运算符优先级 ⑶由于精度问题,造成的比较错误 ⑷错误的变量比较 ⑸错误的循环或无终止的循环 ⑹由循环中分支造成的死循环 ⑺不适当地修改循环变量
  • 126. 在错误处理中常见的问题:⑴错误描述令人莫名其妙 ⑵报告错误与真实错误情况不符 ⑶错误异常在错误处理之前已经发生 ⑷错误异常的条件不正确 ⑸错误描述缺少帮助分析出错的足够信息
  • 127. 3.单元测试 (Unit Testing)单元测试又称模块测试,是针对软件设计的最小单位 ─ 程序模块,进行正确性检验的测试工作。其目的在于发现各模块内部可能存在的各种差错。 单元测试需要从程序的内部结构出发设计测试用例。多个模块可以平行地独立进行单元测试。
  • 128. 单元测试的目的和任务目的:通过对象模块的静态分析与动态测试,使其代码达到模块说明书的要求。 任务: 对模块代码进行编译,发现并纠正其语法错误; 进行静态分析,验证模块结构及其内部调用序列是否正确; 确定模块的测试策略,并据此设计一组测试用例和必要的测试软件; 用选定的测试用例对模块进行测试,直至满足测试终止标准为止; 静态分析与动态测试的重点,均应放在模块内部的重要执行路径、出错处理路径和局部数据结构,也要重视模块的对外接口。 编制单元测试报告。
  • 129. 单元测试的内容在单元测试时,测试者需要依据详细设计说明书和源程序清单,了解该模块的I/O条件和模块的逻辑结构,主要采用白盒测试的测试用例,辅之以黑盒测试的测试用例,使之对任何合理的输入和不合理的输入,都能鉴别和响应。
  • 130. (本页无文本内容)
  • 131. (1) 模块接口测试在单元测试的开始,应对通过被测模块的数据流进行测试。测试项目包括: 调用本模块的输入参数是否正确; 本模块调用子模块时输入给子模块的参数是否正确; 全局量的定义在各模块中是否一致;
  • 132. 在做内外存交换时要考虑: 文件属性是否正确; OPEN与CLOSE语句是否正确; 缓冲区容量与记录长度是否匹配; 在进行读写操作之前是否打开了文件; 在结束文件处理时是否关闭了文件; 正文书写/输入错误, I/O错误是否检查并做了处理。
  • 133. (2) 局部数据结构测试不正确或不一致的数据类型说明 使用尚未赋值或尚未初始化的变量 错误的初始值或错误的缺省值 变量名拼写错或书写错 不一致的数据类型 全局数据对模块的影响
  • 134. (3) 路径测试选择适当的测试用例,对模块中重要的执行路径进行测试。 应当设计测试用例查找由于错误的计算、不正确的比较或不正常的控制流而导致的错误。 对基本执行路径和循环进行测试可以发现大量的路径错误。
  • 135. (4) 错误处理测试出错的描述是否难以理解 出错的描述是否能够对错误定位 显示的错误与实际的错误是否相符 对错误条件的处理正确与否 在对错误进行处理之前,错误条件是否已经引起系统的干预等
  • 136. (5) 边界测试注意数据流、控制流中刚好等于、大于或小于确定的比较值时出错的可能性。对这些地方要仔细地选择测试用例,认真加以测试。 如果对模块运行时间有要求的话,还要专门进行关键路径测试,以确定最坏情况下和平均意义下影响模块运行时间的因素。
  • 137. 单元测试的步骤模块并不是一个独立的程序,在考虑测试模块时,同时要考虑它和外界的联系,用一些辅助模块去模拟与被测模块相联系的其它模块。 驱动模块 (driver) 桩模块 (stub) ── 存根模块
  • 138. (本页无文本内容)
  • 139. 如果一个模块要完成多种功能,可以将这个模块看成由几个小程序组成。必须对其中的每个小程序先进行单元测试要做的工作,对关键模块还要做性能测试。 对支持某些标准规程的程序,更要着手进行互联测试。有人把这种情况特别称为模块测试,以区别单元测试。
  • 140. 4.集成测试(Integrated Testing)集成测试 (组装测试 、联合测试) 通常,在单元测试的基础上,需要将所有模块按照设计要求组装成为系统。这时需要考虑的问题是: 在把各个模块连接起来的时侯,穿越模块接口的数据是否会丢失; 一个模块的功能是否会对另一个模块的功能产生不利的影响;
  • 141. 各个子功能组合起来,能否达到预期要求的父功能; 全局数据结构是否有问题; 单个模块的误差累积起来,是否会放大,从而达到不能接受的程度。 在单元测试的同时可进行组装测试,发现并排除在模块连接中可能出现的问题,最终构成要求的软件系统。
  • 142. 子系统的组装测试特别称为部件测试,它所做的工作是要找出组装后的子系统与系统需求规格说明之间的不一致。 通常,把模块组装成为系统的方式有两种 一次性组装方式 增殖式组装方式
  • 143. 目的:将经过单元测试的模块逐步组装成具有良好一致性的完整的程序。 任务: 制定集成测试实施策略。根据程序的结构,可以选择自顶向下或自底向上或二者混合的两头逼近策略。 确定集成测试的实施步骤,设计测试用例。二者的选择,应有利于揭露在接口关系、访问全局性数据,模块调用序列和出错处理等方面存在的隐患。 进行测试,即在一通过单元测试的基础上,逐一地添加模块。集成测试的目的和任务
  • 144. 策略与步骤 通常采用黑盒测试技术 实施策略: 非渐增式测试 渐增式测试 深度优先 广度优先自顶向下结合 自底向上结合
  • 145. 一次就把所有通过了单元测试的模块组合在一起进行全程序的测试。 缺点:发现错误难以诊断定位。又称“莽撞测试”。 非渐增式集成方式
  • 146. 一次性组装方式 (big bang)它是一种非增殖式组装方式。也叫做整体拼装。 使用这种方式,首先对每个模块分别进行模块测试,然后再把所有模块组装在一起进行测试,最终得到要求的软件系统。
  • 147. (本页无文本内容)
  • 148. 增殖式组装方式这种组装方式又称渐增式组装 首先对一个个模块进行模块测试,然后将这些模块逐步组装成较大的系统 在组装的过程中边连接边测试,以发现连接过程中产生的问题 通过增殖逐步组装成为要求的软件系统。
  • 149. (1) 自顶向下的增殖方式这种组装方式将模块按系统程序结构,沿控制层次自顶向下进行组装。 自顶向下的增殖方式在测试过程中较早地验证了主要的控制和判断点。 选用按深度方向组装的方式,可以首先实现和验证一个完整的软件功能。
  • 150. 自顶向下的集成测试集成测试策略: M1 M2 M3 M4 M5 M6 M7 M8深度优先 M1 M2 M3 M4 M5 M6 M7 M8宽度优先集成步骤: 1.主控模块作为测试驱动 2.下层桩模块,每次一个地被替代为真实模块 3.测试每次真实模块替代的情况 4.回归测试 5.循环2到4,直到整个系统被构造
  • 151. 自顶向下结合方式举例: ADBE模块测试 结合顺序CF深度优先:A、B、E、C、D、F广度优先:A、B、C、D、E、F
  • 152. 自顶向下结合方式举例:(深度优先) A测试 AS2S1S3A加入BS2BS3S4A加入ES2BS3EA加入CCBS3E加入DCBDE加入FCBDEAAFS5
  • 153. (2) 自底向上的增殖方式这种组装的方式是从程序模块结构的最底层的模块开始组装和测试。 因为模块是自底向上进行组装,对于一个给定层次的模块,它的子模块(包括子模块的所有下属模块)已经组装并测试完成,所以不再需要桩模块。在模块的测试过程中需要从子模块得到的信息可以直接运行子模块得到。
  • 154. 集成测试策略:自底向上的集成测试 Mc Ma D2 Mb D1 D3不需要使用桩模块集成步骤: 1.底层模块组合为特定功能的簇 2.编写驱动程序,包括测试簇的输入输出案例 3.测试簇 4.移走驱动程序,向上扩大簇的组合簇4簇1簇2簇3
  • 155. 自底向上结合方式举例: ACBDFEEd1Cd3Fd4Bd2EDd5F
  • 156. 自底向上结合方式举例: McD1MaMbD2D3簇1簇2簇3
  • 157. (3) 混合增殖式测试衍变的自顶向下的增殖测试 首先对输入/输出模块和引入新算法模块进行测试; 再自底向上组装成为功能相当完整且相对独立的子系统; 然后由主模块开始自顶向下进行增殖测试。
  • 158. 自底向上自顶向下的增殖测试 首先对含读操作的子系统自底向上直至根结点模块进行组装和测试; 然后对含写操作的子系统做自顶向下的组装与测试。 回归测试 这种方式采取自顶向下的方式测试被修改的模块及其子模块; 然后将这一部分视为子系统,再自底向上测试。
  • 159. 自顶向下 自底向上 优点 可在测试早期 设计测试用例容易 实现并验证系 统主要功能 不需驱动模块 不需桩模块 缺点 需桩模块 只有到最后程序才 能作为一个整体
  • 160. 混合集成测试方法 在程序结构的高层使用自顶向下的测试策略 在程序结构的较低层使用自底向上的测试策略
  • 161. 5.确认测试(Validation Testing)确认测试又称有效性测试。任务是验证软件的功能和性能及其它特性是否与用户的要求一致。 对软件的功能和性能要求在软件需求规格说明书中已经明确规定。它包含的信息就是软件确认测试的基础。
  • 162. (本页无文本内容)
  • 163. 进行有效性测试(黑盒测试)有效性测试是在模拟的环境 (可能就是开发的环境) 下,运用黑盒测试的方法,验证被测软件是否满足需求规格说明书列出的需求。 首先制定测试计划,规定要做测试的种类。还需要制定一组测试步骤,描述具体的测试用例。
  • 164. 通过实施预定的测试计划和测试步骤,确定 软件的特性是否与需求相符; 所有的文档都是正确且便于使用; 同时,对其它软件需求,例如可移植性、兼容性、出错自动恢复、可维护性等,也都要进行测试
  • 165. 在全部软件测试的测试用例运行完后,所有的测试结果可以分为两类: 测试结果与预期的结果相符。这说明软件的这部分功能或性能特征与需求规格说明书相符合,从而这部分程序被接受。 测试结果与预期的结果不符。这说明软件的这部分功能或性能特征与需求规格说明不一致,因此要为它提交一份问题报告。
  • 166. 软件配置复查 软件配置复查的目的是保证 软件配置的所有成分都齐全; 各方面的质量都符合要求; 具有维护阶段所必需的细节; 而且已经编排好分类的目录。 应当严格遵守用户手册和操作手册中规定的使用步骤,以便检查这些文档资料的完整性和正确性。
  • 167. 验收测试(Acceptance Testing)在通过了系统的有效性测试及软件配置审查之后,就应开始系统的验收测试。 验收测试是以用户为主的测试。软件开发人员和QA(质量保证)人员也应参加。 由用户参加设计测试用例,使用生产中的实际数据进行测试。
  • 168. 在测试过程中,除了考虑软件的功能和性能外,还应对软件的可移植性、兼容性、可维护性、错误的恢复功能等进行确认。 确认测试应交付的文档有: 确认测试分析报告 最终的用户手册和操作手册 项目开发总结报告。
  • 169. α测试和β测试在软件交付使用之后,用户将如何实际使用程序,对于开发者来说是无法预测的。 α测试是由一个用户在开发环境下进行的测试,也可以是公司内部的用户在模拟实际操作环境下进行的测试。
  • 170. α测试的目的是评价软件产品的FLURPS(即功能、局域化、可使用性、可靠性、性能和支持)。尤其注重产品的界面和特色。 α测试可以从软件产品编码结束之时开始,或在模块(子系统)测试完成之后开始,也可以在确认测试过程中产品达到一定的稳定和可靠程度之后再开始。
  • 171. β测试是由软件的多个用户在实际使用环境下进行的测试。这些用户返回有关错误信息给开发者。 测试时,开发者通常不在测试现场。因而,β测试是在开发者无法控制的环境下进行的软件现场应用。 在β测试中,由用户记下遇到的所有问题,包括真实的以及主观认定的,定期向开发者报告。
  • 172. β测试主要衡量产品的FLURPS。着重于产品的支持性,包括文档、客户培训和支持产品生产能力。 只有当α测试达到一定的可靠程度时,才能开始β测试。它处在整个测试的最后阶段。同时,产品的所有手册文本也应该在此阶段完全定稿。
  • 173. 6.系统测试(System Testing)系统测试,是将通过确认测试的软件,作为整个基于计算机系统的一个元素,与计算机硬件、外设、某些支持软件、数据和人员等其它系统元素结合在一起,在实际运行环境下,对计算机系统进行一系列的组装测试和确认测试。 系统测试的目的在于通过与系统的需求定义作比较, 发现软件与系统的定义不符合或与之矛盾的地方。
  • 174. 测试种类软件测试是由一系列不同的测试组成。主要目的是对以计算机为基础的系统进行充分的测试。 功能测试 功能测试是在规定的一段时间内运行软件系统的所有功能,以验证这个软件系统有无严重错误。
  • 175. 可靠性测试 如果系统需求说明书中有对可靠性的要求,则需进行可靠性测试。 ① 平均失效间隔时间 MTBF (Mean Time Between Failures) 是否超过规定时限? ② 因故障而停机的时间 MTTR (Mean Time To Repairs) 在一年中应不超过多少时间。
  • 176. 强度测试 强度测试是要检查在系统运行环境不正常乃至发生故障的情况下,系统可以运行到何种程度的测试。例如: 把输入数据速率提高一个数量级,确定输入功能将如何响应。 设计需要占用最大存储量或其它资源的测试用例进行测试。
  • 177. 设计出在虚拟存储管理机制中引起“颠簸”的测试用例进行测试。 设计出会对磁盘常驻内存的数据过度访问的测试用例进行测试。 强度测试的一个变种就是敏感性测试。在程序有效数据界限内一个小范围内的一组数据可能引起极端的或不平稳的错误处理出现,或者导致极度的性能下降的情况发生。此测试用以发现可能引起这种不稳定性或不正常处理的某些数据组合。
  • 178. 性能测试 性能测试是要检查系统是否满足在需求说明书中规定的性能。特别是对于实时系统或嵌入式系统。 性能测试常常需要与强度测试结合起来进行,并常常要求同时进行硬件和软件检测。 通常,对软件性能的检测表现在以下几个方面:响应时间、吞吐量、辅助存储区,例如缓冲区,工作区的大小等、处理精度,等等。
  • 179. 恢复测试 恢复测试是要证实在克服硬件故障(包括掉电、硬件或网络出错等)后,系统能否正常地继续进行工作,并不对系统造成任何损害。 为此,可采用各种人工干预的手段,模拟硬件故障,故意造成软件出错。并由此检查: 错误探测功能──系统能否发现硬件失效与故障;
  • 180. 能否切换或启动备用的硬件; 在故障发生时能否保护正在运行的作业和系统状态; 在系统恢复后能否从最后记录下来的无错误状态开始继续执行作业,等等。 掉电测试:其目的是测试软件系统在发生电源中断时能否保护当时的状态且不毁坏数据,然后在电源恢复时从保留的断点处重新进行操作。
  • 181. 启动/停止测试 这类测试的目的是验证在机器启动及关机阶段,软件系统正确处理的能力。 这类测试包括 反复启动软件系统 (例如,操作系统自举、网络的启动、应用程序的调用等) 在尽可能多的情况下关机。
  • 182. 配置测试 这类测试是要检查计算机系统内各个设备或各种资源之间的相互联结和功能分配中的错误。 它主要包括以下几种: 配置命令测试:验证全部配置命令的可操作性(有效性);特别对最大配置和最小配置要进行测试。软件配置和硬件配置都要测试。
  • 183. 循环配置测试:证明对每个设备物理与逻辑的,逻辑与功能的每次循环置换配置都能正常工作。 修复测试:检查每种配置状态及哪个设备是坏的。并用自动的或手工的方式进行配置状态间的转换。
  • 184. 安全性测试 安全性测试是要检验在系统中已经存在的系统安全性、保密性措施是否发挥作用,有无漏洞。 力图破坏系统的保护机构以进入系统的主要方法有以下几种: 正面攻击或从侧面、背面攻击系统中易受损坏的那些部分; 以系统输入为突破口,利用输入的容错性进行正面攻击;
  • 185. 申请和占用过多的资源压垮系统,以破坏安全措施,从而进入系统; 故意使系统出错,利用系统恢复的过程,窃取用户口令及其它有用的信息; 通过浏览残留在计算机各种资源中的垃圾(无用信息),以获取如口令,安全码,译码关键字等信息; 浏览全局数据,期望从中找到进入系统的关键字; 浏览那些逻辑上不存在,但物理上还存在的各种记录和资料等。
  • 186. 可使用性测试 可使用性测试主要从使用的合理性和方便性等角度对软件系统进行检查,发现人为因素或使用上的问题。 要保证在足够详细的程度下,用户界面便于使用;对输入量可容错、响应时间和响应方式合理可行、输出信息有意义、正确并前后一致;出错信息能够引导用户去解决问题;软件文档全面、正规、确切。
  • 187. 可支持性测试 这类测试是要验证系统的支持策略对于公司与用户方面是否切实可行。 它所采用的方法是 试运行支持过程(如对有错部分打补丁的过程,热线界面等); 对其结果进行质量分析; 评审诊断工具; 维护过程、内部维护文档; 修复一个错误所需平均最少时间。
  • 188. 安装测试 安装测试的目的不是找软件错误,而是找安装错误。 在安装软件系统时,会有多种选择。 要分配和装入文件与程序库 布置适用的硬件配置 进行程序的联结。 而安装测试就是要找出在这些安装过程中出现的错误。
  • 189. 安装测试是在系统安装之后进行测试。它要检验: 用户选择的一套任选方案是否相容; 系统的每一部分是否都齐全; 所有文件是否都已产生并确有所需要的内容; 硬件的配置是否合理,等等。
  • 190. 过程测试 在一些大型的系统中,部分工作由软件自动完成,其它工作则需由各种人员,包括操作员,数据库管理员,终端用户等,按一定规程同计算机配合,靠人工来完成。 指定由人工完成的过程也需经过仔细的检查,这就是所谓的过程测试。
  • 191. 互连测试 互连测试是要验证两个或多个不同的系统之间的互连性。 兼容性测试 这类测试主要想验证软件产品在不同版本之间的兼容性。有两类基本的兼容性测试: 向下兼容 交错兼容
  • 192. 容量测试 容量测试是要检验系统的能力最高能达到什么程度。例如, 对于编译程序,让它处理特别长的源程序; 对于操作系统,让它的作业队列“满员”; 对于信息检索系统,让它使用频率达到最大。 在使系统的全部资源达到“满负荷”的情形下,测试系统的承受能力。
  • 193. 文档测试 这种测试是检查用户文档(如用户手册)的清晰性和精确性。 用户文档中所使用的例子必须在测试中一一试过,确保叙述正确无误。
  • 194. 调试(Debug)软件调试是在进行了成功的测试之后才开始的工作。它与软件测试不同,调试的任务是进一步诊断和改正程序中潜在的错误。 调试活动由两部分组成: 确定程序中可疑错误的确切性质和位置。 对程序(设计,编码)进行修改,排除这个错误。
  • 195. 调试工作是一个具有很强技巧性的工作。 软件运行失效或出现问题,往往只是潜在错误的外部表现,而外部表现与内在原因之间常常没有明显的联系。如果要找出真正的原因,排除潜在的错误,不是一件易事。 可以说,调试是通过现象,找出原因的一个思维分析的过程。
  • 196. 调试的步骤(1) 从错误的外部表现形式入手,确定程序中出错位置; (2) 研究有关部分的程序,找出错误的内在原因; (3) 修改设计和代码,以排除这个错误; (4) 重复进行暴露了这个错误的原始测试或某些有关测试。
  • 197. 从技术角度来看,查找错误的难度在于: 现象与原因所处的位置可能相距甚远。 当其它错误得到纠正时,这一错误所表现出的现象可能会暂时消失,但并未实际排除。 现象实际上是由一些非错误原因(例如,舍入不精确)引起的。
  • 198. 现象可能是由于一些不容易发现的人为错误引起的。 错误是由于时序问题引起的,与处理过程无关。 现象是由于难于精确再现的输入状态(例如,实时应用中输入顺序不确定)引起。 现象可能是周期出现的。在软、硬件结合的嵌入式系统中常常遇到。
  • 199. 几种主要的调试方法调试的关键在于推断程序内部的错误位置及原因。可以采用以下方法: 强行排错 这种调试方法目前使用较多,效率较低。它不需要过多的思考,比较省脑筋。例如: 通过内存全部打印来调试,在这大量的数据中寻找出错的位置。
  • 200. 在程序特定部位设置打印语句,把打印语句插在出错的源程序的各个关键变量改变部位、重要分支部位、子程序调用部位,跟踪程序的执行,监视重要变量的变化。 自动调试工具。利用某些程序语言的调试功能或专门的交互式调试工具,分析程序的动态过程,而不必修改程序。
  • 201. 应用以上任一种方法之前,都应当对错误的征兆进行全面彻底的分析,得出对出错位置及错误性质的推测,再使用一种适当的调试方法来检验推测的正确性。 回溯法调试 这是在小程序中常用的一种有效的调试方法。 一旦发现了错误,人们先分析错误征兆,确定最先发现“症状”的位置。
  • 202. 然后,人工沿程序的控制流程,向回追踪源程序代码,直到找到错误根源或确定错误产生的范围。 例如,程序中发现错误处是某个打印语句。通过输出值可推断程序在这一点上变量的值。再从这一点出发,回溯程序的执行过程,反复考虑:“如果程序在这一点上的状态(变量的值)是这样,那么程序在上一点的状态一定是这样...”, 直到找到错误的位置。
  • 203. 归纳法调试 归纳法是一种从特殊推断一般的系统化思考方法。归纳法调试的基本思想是:从一些线索(错误征兆)着手,通过分析它们之间的关系来找出错误。 收集有关的数据 列出所有已知的测试用例和程序执行结果。看哪些输入数据的运行结果是正确的,哪些输入数据的运行结果有错误。
  • 204. 组织数据 由于归纳法是从特殊到一般的推断 过程,所以需要组织整理数据,以 发现规律。 常以3W1H形式组织可用的数据: “What” 列出一般现象; “Where”说明发现现象的地点; “When” 列出现象发生时所有已知情况; “How” 说明现象的范围和量级;
  • 205. (本页无文本内容)
  • 206. “Yes”描述出现错误的3W1H; “No”作为比较,描述了没有错误的3W1H。通过分析找出矛盾来。 提出假设 分析线索之间的关系,利用在线索结构中观察到的矛盾现象,设计一个或多个关于出错原因的假设。如果一个假设也提不出来,归纳过程就需要收集更多的数据。此时,应当再设计与执行一些测试用例,以获得更多的数据。
  • 207. 证明假设 把假设与原始线索或数据进行比较,若它能完全解释一切现象,则假设得到证明;否则,就认为假设不合理,或不完全,或是存在多个错误,以致只能消除部分错误。
  • 208. 演绎法调试 演绎法是一种从一般原理或前提出发,经过排除和精化的过程来推导出结论的思考方法。演绎法排错是测试人员首先根据已有的测试用例,设想及枚举出所有可能出错的原因做为假设;然后再用原始测试数据或新的测试,从中逐个排除不可能正确的假设;最后,再用测试数据验证余下的假设确是出错的原因。
  • 209. 列举所有可能出错原因的假设 把所有可能的错误原因列成表。通过它们,可以组织、分析现有数据。 利用已有的测试数据,排除不正确的假设 仔细分析已有的数据,寻找矛盾,力求排除前一步列出所有原因。如果所有原因都被排除了,则需要补充一些数据(测试用例),以建立新的假设。
  • 210. 改进余下的假设 利用已知的线索,进一步改进余下的假设,使之更具体化,以便可以精确地确定出错位置。 证明余下的假设
  • 211. 调试原则在调试方面,许多原则本质上是心理学方面的问题。调试由两部分组成,调试原则也分成两组。 确定错误的性质和位置的原则 用头脑去分析思考与错误征兆有关的信息。 避开死胡同。
  • 212. 只把调试工具当做辅助手段来使用。利用调试工具,可以帮助思考,但不能代替思考。 避免用试探法,最多只能把它当做最后手段。 修改错误的原则 在出现错误的地方,很可能还有别的错误。
  • 213. 修改错误的一个常见失误是只修改了这个错误的征兆或这个错误的表现,而没有修改错误的本身。 当心修正一个错误的同时有可能会引入新的错误。 修改错误的过程将迫使人们暂时回到程序设计阶段。 修改源代码程序,不要改变目标代码。
  • 214. 9.7 面向对象系统的测试 面向对象的测试与传统测试的目标是一致的视角----扩大到分析和设计模型的评审 焦点----不是模块,而是类单元测试和集成测试:面向对象测试的视角和焦点:单元测试使用的方法----故障测试、随机测试、划分测试 集成测试使用的方法----基于线程的、基于使用的和基于行为的测试白盒测试和黑盒测试:白盒测试----可用于类的操作测试,但由于类操作的简洁,有人 对必要性产生质疑。 黑盒测试----通过使用use-case,可用于系统确认性测试
  • 215. 分析和设计模型的评审表示分析模型和设计模型的符号体系和语法检查 专家评审类定义符合现实问题的表示程度,有无 遗漏和歧义性的检查  OOA和OOD模型的表示一致性OOA和OOD模型的正确性评审途径:
  • 216. CRC卡----OOA和OOD模型的表示一致性工具分析和设计模型的评审CRC卡例:类名:credit sale 类的类型:交易事件 类的特征:确切的、原子的、顺序的、永久的、保护的 责任: 协作者: read credit card credit card get authorization credit authority post purchase amount product ticket sales ledger audit file generate bill bill
  • 217. 故障测试方法单元测试•从分析模型开始查找可能的故障 •对可能的故障设计案例,使之执行不正确表达式,导致失败例如:if(x>=0)calculate_the_square_root 错误写为: if(x>0)calculate_the_square_root 将会在边值处理时发生问题 又如:布尔表达式 if(a || !b || c) 错误写为: if(a && !b || c) 将会在真假条件上发生错误 这项技术的成功依赖于测试人员的感觉。 遗憾的是,模型中并没有提供出错的洞察点。
  • 218. 随机测试方法单元测试分析类中最小的测试序列和最大的操作序列 在最小和最大序列之间,随机产生一系列不同的操作案例例:银行单机ATM自动取款 账户account类上的所有操作:open,setup,deposit,withdraw,balance,summarize,creditLimit,close 账户的最小生命历史应该包括的操作: open.setup.deposit.withdraw.close 账户的其他行为都包含在下列操作中:(最大包容) open.setup.deposit.[deposit|withdraw|balance|summarize| creditLimit|]n .withdraw. close这样可随基地产生测试账户类的案例: 测试案例1:open.setup.deposit.balance.summarize.withdraw. close 测试案例2:open.setup.deposit.withdraw.balance.creditLimit.withdraw.close .....
  • 219. 划分测试方法单元测试按状态、属性、操作分别归类所有的操作,设计测试案例,达到减少测试案例的功效例如:账户类account ①基于状态的划分: 状态操作包括(deposit和withdraw), 非状态操作包括(balance,summarize和creditLimit) 这样,可设计测试案例: 测试案例1:open.setup.deposit. deposit. withdraw.withdraw. close 测试案例2:open.setup.deposit.summarize. creditLimit.withdraw. close
  • 220. 划分测试方法单元测试例如:账户类account ②基于属性的划分: 对于属性balance和creditLimit,可定义的操作分为: “使用creditLimit” “修改creditLimit” 分别涉及3个测试案例 “不使用或不修改操作creditLimit” ③基于操作类别的划分: 按操作分类: 初始化操作( open、setup) 计算操作(deposit、withdraw) 分别涉及4个测试案例 查询操作(balance、summarize、creditLimit) 终止操作(close)
  • 221. 基于线程的测试方法 (thread based testing)集成测试•分析系统的每个输入或事件所需要的一组类,它 们在一个线程中 •每个线程独立地集成测试 •使用协作图可对应用的类规划测试案例
  • 222. 例:银行应用的类,用协作图规划测试案例card inserted password deposit withdraw accntStatus terminateverify accnt verity PIN verity policy with drawReq deppositReq acctInfoReqverity Status deposit Status disppoense cash print AccntStar read CardInfo getCashAmntopen accnt initialDeposit authorizeCard deauthorize close accntdeposit creditLimit accntType balance withdraw deposit closevalid accnt valid PIN ATM user interface ATM Bank Cashier Account Validation Info基于线程的测试方法 (thread based testing)集成测试例:蓝字标出取款操作的线程
  • 223. 基于使用的测试方法 (use based testing)集成测试逐层测试类的方法: •由几乎不使用其它服务类的那些独立类开始,逐层 测试与其它服务密切的层,直至全部系统 •通过用例图(Use Case),捕获用户必须完成的任务。 进行案例设计集成测试总是试图在客户而不是服务中找到错误,既从使用角度寻找错误
  • 224. 基于行为的测试方法 (use based testing)集成测试例:从account类行为模型导出测试案例:Empty accntSet up accntWorking accntNon working accntDead accntopenSetup AccntDeposit(init)depositWithdraw(final)closeBalance credit accntInfoWithdraw设计的案例应该能完全状态覆盖1.open.setupAccnt.deposit(initial).withdraw(final).close 2.open.setupAccnt.deposit(initial).deposit.balance.credit. withdraw(final).close 3.open.setupAccnt.deposit(initial).deposit. withdraw.accntInfo.withdraw(final).close 测试案例
  • 225. 测试一个面向对象的应用传统软件测试经历单元测试、组装测试、确认测试和系统测试等4个阶段。 单元测试主要针对最小的程序单元程序模块进行测试。 一旦这些程序模块分别测试完成后,就将它们组装起来形成程序结构。 对整个系统进行一系列的测试,查找和排除在需求方面的问题。
  • 226. 面向对象环境下的测试策略单元测试 (类测试) 在面向对象环境下,最小的可测试的单元是封装了的类或对象,而不是程序模块。 面向对象软件的类测试等价于传统软件开发方法中的单元测试。但它是由类中封装的操作和和类的状态行为驱动的。 完全孤立地测试类的各个操作是不行的。
  • 227. 考虑一个类的层次。在基类中我们定义了一个操作X。 每一个派生类都使用操作X,它是在各个类所定义的私有属性和操作的环境中使用的。因使用操作X的环境变化太大,所以必须在每一个派生类的环境下都测试操作X。 在面向对象开发环境下,把操作完全孤立起来进行测试,其收效是很小的。
  • 228. 组装测试 因为面向对象软件没有一个层次的控制结构,所以传统的自顶向下和自底向上的组装策略意义不大。 每次将一个操作组装到类中(像传统的增殖式组装那样)常常行不通,因为在构成类的各个部件之间存在各种直接的和非直接的交互。 对于面向对象系统的组装测试,存在两种不同的测试策略。
  • 229. 基于线索测试 (Thread-based Test) 它把为响应某一系统输入或事件所需的一组类组装在一起。每一条线索将分别测试和组装。 基于应用的测试 (Use-based Test) 它着眼于系统结构,首先测试独立类,这些类只使用很少的服务器类。再测试那些使用了独立类的相关类。一系列测试各层相关类的活动继续下去,直到整个系统构造完成。
  • 230. 确认测试 在进行确认测试和系统测试时,不关心类之间连接的细节。着眼于用户的要求和用户能够认可的系统输出。 为了帮助确认测试的执行,测试者需要回到分析模型,根据那里提供的事件序列(脚本)进行测试。 可以利用黑盒测试的方法来驱动确认测试。
  • 231. 测试方法学检测软件中的故障并确定软件是否执行了预定要开发的功能。 测试过程包括了一组测试用例的开发,每一个测试用例要求能检验应用的一个特定的元素。还需要分析用各个测试用例执行测试的结果来收集有关软件的信息。
  • 232. 按不同层次进行测试测试类中各个操作,主要测试类 这种测试是某些单元测试与组装测试的组合 假定测试一个软件与测试一个类一样。这个测试者常常就是一个特定类的开发者。 下面讨论测试,主要集中于测试类和它们的各个操作,而不考虑确认测试或其它系统测试。
  • 233. 类的测试用例组一个类的测试用例组由满足测试需求的用例组成。 每个测试用例是一系列输入值,它们将在要求的处理中执行,以满足测试需求。 每个测试用例应当包括送给构造函数的参数,以把对象在测试之前置于一个初始化的状态中。
  • 234. (本页无文本内容)
  • 235. 类测试类,作为在语法上独立的部件,应当允许用在许多不同的应用中。 每个类都应是可靠的,并且不需了解任何实现的细节就能复用。 因此,类应尽可能孤立地进行测试。
  • 236. 测试类操作的测试用例组首先定义测试类的各个操作的测试用例组。 然后再把测试用例组扩充,针对被测操作调用类中其它操作的情况,进行组装测试。 如果一个类中的所有操作的先决条件和后置条件都已定下来,就为各个独立操作的测试用例的开发提供了指导。
  • 237. 类测试的种类基于定义的测试 把类当做一个黑盒对待,确认类的实现是否遵照它的定义。例如,若类是一个“Stack”,则测试应当确保 LIFO 原则得以实施。 基于程序的测试 考虑类的实现,确定代码编写得是否正确。例如,在stack类中,确认所有语句至少应被运行一次,同时正确地执行了操作。
  • 238. 基于定义的测试基于定义的测试包括两个级别:类定义和服务定义。 类定义 一个类的定义由各个服务的定义和一些表示类的概念的语句组合而成。 例,一个stack类包括了服务push和pop的定义。还表达了 LIFO 的思想。 C++中类的定义是多层次的。 对于大多数的类,检验类的定义 主要检验在类定义的public域中所包含的那些服务。 对于派生类,要检查包括public和protected这两个域在内的扩充界面。 如果完全地检查类中定义的服务,则需要检查包括所有三个访问级别public,protected以及private的界面。
  • 239. 服务定义 对于一个单独的服务,可通过该服务的先决条件和后置条件,以及它的名字加以定义。 根据先决条件选择测试用例,产生输出,以便让测试者能够判断后置条件是否能够得到满足。 各个服务的定义的测试与对于各个过程定义的测试基本相同。
  • 240. 基于程序的测试基于程序的类的测试将测试类的各个服务,并把类当做一个单元进行测试。 首先,测试计划考虑测试属于该类的各个单个服务中的代码 然后考虑测试各个服务之间的相互作用:类内通信 / 类间通信。
  • 241. (本页无文本内容)
  • 242. 测试可以覆盖每个服务的整个输入域。但这是不够的,还必须测试这些服务的相互作用,才能认为测试是充分的。 完全的单元应当保证类的执行必须覆盖它的一个有代表性的状态集合。 构造函数和消息序列(线索)的参数值的选择应当满足这个规则。
  • 243. 处于隔离的服务基于程序的测试考虑测试每一个单独的服务,可以使用那些与过程性测试相同的方式对它们进行测试。 在测试一个服务与测试一个过程之间最明显的不同就是服务可能会改变它所在的实例的状态。 在测试一个服务时,该服务发送给其它实例的消息都将被隔离,由桩(stub)代替其它实例返回合适的值。
  • 244. 处于组装的服务基于程序的测试需要考虑 在同一个类内部一个服务调用另一个服务时的相互作用(类内消息) 从一个类到另一个类的消息(类间消息)。 加入检查相互作用的测试用例到测试用例组中,确定这种交互影响是否处理得当。 类内测试需要执行类的所有主要的状态。
  • 245. 组装测试类组装 测试一个新类时,需要先测试在定义中所涉及的类,再考虑这些类的组装。 关系“is a”“is part of”和“refers to”建立了测试几个类时的次序之间的关联。一旦基本类测试完成,使用这些类的那些类可以接着测试,然后按层次继续测试下去。
  • 246. 总体组装 把所有组成完整软件的各个部分集合在一起。 在C++的主过程中,仅建立几个高层的和全局的类的实例,这些实例之间必须经常互相通信。 这种测试所选择的测试用例应当瞄准待开发软件的目标,并且应当提供数据给测试者,以确定软件开发是否与它的目标相吻合。
  • 247. 测试一个派生类对基类和继承关系进行完全测试。 从基类的测试用例组复用已存在的测试用例到派生类的测试用例组中。这种技术基于类的带有祖先的层次关系,渐增地开发类的测试用例组,因此叫做分层增殖式测试。 我们首先安排一个针对单独的类的测试计划,然后考虑分层增殖式测试计划和算法。