通常把编码和测试统称为实现.ppt

上传人:xian****812 文档编号:6365830 上传时间:2020-02-24 格式:PPT 页数:98 大小:963.31KB
返回 下载 相关 举报
通常把编码和测试统称为实现.ppt_第1页
第1页 / 共98页
通常把编码和测试统称为实现.ppt_第2页
第2页 / 共98页
通常把编码和测试统称为实现.ppt_第3页
第3页 / 共98页
点击查看更多>>
资源描述
通常把编码和测试统称为实现 编码就是把软件设计结果翻译成用某种程序设计语言书写的程序 测试的目的就是在软件投入生产性运行之前 尽可能多地发现软件中的错误 第七章实现 软件测试在软件生命周期中横跨两个阶段 单元测试 通常在编写出每个模块之后就对它做必要的测试 称为单元测试 模块的编写者和测试者是同一个人 编码和单元测试属于软件生命周期的同一个阶段 综合测试 在这个阶段结束之后 对软件系统还应该进行各种综合测试 这是软件生命周期中的另一个独立的阶段 通常由专门的测试人员承担这项工作 大量统计资料表明 软件测试的工作量往往占软件开发总工作量的40 以上 7 1 1程序设计语言 7 1编码 1程序设计语言的分类 大体上 程序设计语言分为以下几类 1 机器语言 2 汇编语言 3 高级语言 由于高级语言种类繁多 我们可以从应用特点 语言内在特点和对客观系统的描述三个不同的角度来对高级语言进行分类 1 基础语言 例 FORTRAN BASIC COBOL和ALGOL 2 结构化语言 例 ALGOL PL 1 PASCAL C Ada 3 专用语言 例 APL LISP PROLOG BLISS FORTH 1 从应用特点的角度来分 1 系统实现语言 例 C语言 2 静态高级语言 例 FORTRAN COBOL 3 块结构高级语言 例 PASCAL ALGOL 4 动态高级语言 2 从语言内在特点的角度来分 2 面向对象语言对象 消息 1 面向过程语言数据结构 算法 3 从描述客观系统的角度来分 例 Delphi VisualBasic JAVA C 2程序设计语言的特点 1 名字说明2 类型说明3 选择控制结构4 循环控制结构5 程序对象的局部性6 变量的局部共享7 异常处理8 独立编译 3程序设计语言的选择 一般情况下 我们采用高级语言来编程 选择具体高级语言类型的原则 1 系统的应用领域 2 用户的要求 3 软件的执行环境 4 目标系统的性能要求 5 程序员的知识水平 6 软件的可移植性要求 程序内部的文档包括 1 恰当的标识符 变量和标号 的名字 2 适当的注释 3 程序的视觉组织 1程序内部的文档 7 1 2编码风格 为了使数据更容易理解和维护 应遵循一些简单的原则 1 数据说明的次序应当规范化 2 当多个变量名在一个语句中说明时 应该按字母顺序排列这些变量 3 如果设计时使用了一个复杂的数据结构 则应注解说明用程序设计语言实现这个数据结构的方法和特点 2数据说明 语句构造应遵循的原则是 每条语句应该简单而直接 不应为了片面追求效率而使代码变得过于复杂 3语句构造 人们在长期的实践中总结了以下一些规则 不要为了节省空间而把多个语句写在同一行 用空格或可读的符号使语句的内容更加清晰 尽量避免复杂的条件测试 尽量避免使用 非 条件的条件语句 避免过多使用循环嵌套和条件嵌套 利用括号使逻辑表达式或算术表达式的运算次序清晰直观 尽可能使用库函数 让编译程序作简单的优化 在设计和程序编码时 应考虑输入和输出风格原则 对所有输入数据都进行校验 以保证每个数据的有效性 检查重要的输入项组合的合法性 使得输入的步骤和操作尽可能简单 并保持简单的输入格式 输入一批数据时 使用输入结束指示符 不要要求用户说明输入项数 在以交互式输入 输出方式进行输入时 要指明可以使用的选择值或界限值 应允许缺省值 当程序设计语言对输入 输出格式有严格要求时 应保持输入格式与输入语句的要求一致 给所有的输出加注释 并设计输出报表格式 4输入 输出 通常 效率主要指占用处理机时间和主存区域两个方面 好的编码可以提高效率 在我们进一步讨论这个问题之前 应该记住三条原则 第一 效率是一个性能要求 因而应该在需求分析阶段确定代码效率方面的要求 第二 通过好的设计可以提高效率 第三 程序的效率和程序的简明程度是一致的 不应该为了提高代码效率而牺牲程序的清晰性和可读性 5效率 1 代码效率 2 存储效率 3 输入 输出的效率 为了提高编码的效率 保证程序的可靠性 我们经常使用一些编码工具 首先要用的当然是编辑工具了 选用合适的编辑工具可以大大方便编程 提高效率 编译程序的好坏也会影响编码的效率 一方面 好的编译程序应该是程序员的好助手 能够帮助程序员及时准确地诊断出程序中的差错 减少程序开发的成本 另一方面 编译程序还应该能够生成高效率的机器代码 也就是代码优化 编码工具 7 2软件测试基础 关于测试目的 G Myers给出了以下的观点 1 测试是为了发现程序中的错误而执行程序的过程 2 好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案 3 成功的测试是发现了至今为止尚未发现的错误的测试 测试的定义 为了发现程序中的错误而执行程序的过程 具体地说 软件测试是根据软件开发各阶段的规格说明和程序的内部结构而精心设计出一批测试用例 并利用测试用例来运行程序 以发现程序错误的过程 7 2 1软件测试的定义 7 2 2软件测试的基本原则 1 尽早地 不断地进行软件测试 2 设计测试用例时 要给出测试的预期结果 3 开发小组和测试小组分开 4 要设计非法输入的测试用例 5 在对程序修改之后要进行回归测试 6 程序中尚未发现的错误的数量往往与在该段程序中已发现的错误的数量成正比 7 2 3软件测试的方法 测试任何产品都有两种方法 如果已经知道了产品应该具有的功能 可以通过测试来检验是否每个功能都能正常使用 这种方法称为黑盒测试 如果知道产品的内部工作过程 可以通过测试来检验产品内部动作是否按照规格说明书的规定正常进行 这种方法称为白盒测试 大型软件系统通常由若干个子系统组成 每个子系统又由许多模块组成 因此 测试过程也必须分步骤进行 后一个步骤在逻辑上是前一个步骤的继续 大型软件系统的测试过程基本上由下述几个步骤组成 7 2 4软件测试的步骤 1 单元测试又称模块测试 每个程序模块完成一个相对独立的子功能 所以可以对该模块进行单独的测试 由于每个模块都有清晰定义的功能 所以通常比较容易设计相应的测试方案 以检验每个模块的正确性 2 子系统测试子系统测试是把经过单元测试的模块放在一起形成一个子系统来测试 模块相互间的协调和通信是这个测试过程中的主要问题 因此 这个步骤着重测试模块的接口 3 系统测试系统测试是把经过测试的子系统装配成一个完整的系统来测试 在这个过程中不仅应该发现设计和编码的错误 还应该验证系统确实能提供需求说明书中指定的功能 而且系统的动态特性也符合预定要求 在这个测试步骤中发现的往往是软件设计中的错误 也可能发现需求说明中的错误 不论是子系统测试还是系统测试 都兼有检测和组装两重含义 通常称为集成测试 4 验收测试验收测试把软件系统作为单一的实体进行测试 测试内容与系统测试基本类似 但是它是在用户积极参与下进行的 而且可能主要使用实际数据 系统将来要处理的信息 进行测试 验收测试的目的是验证系统确实能够满足用户的需要 在这个测试步骤中发现的往往是系统需求说明书中的错误 验收测试也称为确认测试 5 平行运行所谓平行运行就是同时运行新开发出来的系统和将被它取代的旧系统 以便比较新旧两个系统的处理结果 这样做的具体目的有如下几点 1 可以在准生产环境中运行新系统而又不冒风险 2 用户能有一段熟悉新系统的时间 3 可以验证用户指南和使用手册之类的文档 4 能够以准生产模式对新系统进行全负荷测试 可以用测试结果验证性能指标 7 2 5软件测试信息流 单元测试又称模块测试 集中对软件设计的最小单位 模块进行测试 主要是为了发现模块内部可能存在的各种错误和不足 进行单元测试时 根据程序的内部结构设计测试用例 主要使用白盒测试法 由于各模块间相对独立 因而对多个模块的测试可以并行地进行 以提高测试效率 7 3单元测试 软件测试的步骤 1 单元测试的内容 1 模块接口主要进行的测试项目有以下几方面 所测模块的形式参数和调用该模块的实际输入参数在参数数目 属性和顺序上是否匹配 是否修改了只做输入用的形式参数 输出给被调用模块的参数在数目 属性和顺序上是否正确 全程变量的定义和用法在各个模块中是否一致 若模块中有外部的I O操作 还应该进行以下的测试项目 文件属性是否正确 打开文件语句和关闭语句是否正确 格式说明书与输入 输出语句是否一致 缓冲区的大小与记录长度是否匹配 使用文件之前是否先打开了文件 文件操作结束后是否关闭了文件 是否进行了输入 输出错误检查并进行了相应的处理 2 局部数据结构 模块的局部数据结构是常见的错误来源 测试者应该仔细设计测试用例 以便发现这样一些类型的错误 错误的变量名 变量名拼写错或被编译程序截短 错误的或不一致的数据类型说明 使用尚未赋值或尚未初始化的变量 错误的初始值或错误的缺省值 数据类型不相容 上溢 下溢或地址异常 如果有可能的话 在单元测试期间除了局部数据结构之外 还应该检查全程数据对模块的影响 3 重要的执行路径 选择适当的测试用例 对模块中的最有代表性 最可能发现错误的执行路径进行测试 错误的计算主要集中在以下几个方面 运算的优先次序不对或误解了运算符的优先次序 混合运算 运算对象的类型彼此不相容 变量的初始值赋值不正确 运算的精度不够 表达式的符号有错误 错误的比较和控制流主要集中在以下几个方面 不同数据类型之间的比较 逻辑运算符不正确或优先次序不正确 由于精度问题造成的两值比较时不相等 差 1 错 即循环次数多一次或少一次 错误的或不可能的循环终止条件 当遇到发散的迭代时不能终止的循环 错误地修改循环变量 4 出错处理 由于输入等条件的限制 程序在运行中出错往往是不可避免的 因而好的程序设计应该能预见可能出现的各种出错情况 并且设置相应的出错处理 以便在出现错误时执行相应的操作 在单元测试时也应该对模块中的出错处理部分进行测试 进行这一部分测试时可能存在的错误主要有 对错误的描述难于理解 或者是描述过于简单 显示的错误信息与实际错误不相符 在对错误进行处理之前 错误条件已经引起系统的干预 对错误的处理不正确 5 边界条件 我们知道 软件常常在它的边界上失效 例如 处理n元数组的第一个元素或最后一个元素时 在n次循环中的第n次重复时 往往会发生错误 因此 使用刚好小于 等于或大于最大值或最小值的数据结构 控制量和数据值的测试方案时 很可能会发现软件中的错误 2 单元测试的步骤 单元测试的对象是模块 测试者必须自己动手设计这两类模块 驱动模块和存根模块 驱动模块 相当于所测模块的 主程序 它接收测试数据 把这些数据传送给所测模块 然后输出测试结果 存根模块 也叫虚拟子程序 它的作用是模拟被测模块所调用的子模块 存根模块可以做少量的数据操作 一般情况下 不需要把实际子模块的所有功能都带进来 7 4集成测试 集成测试过程中要考虑的问题 1 数据穿过模块接口时是否会丢失 2 模块的功能是否会对其它模块的功能产生不利的影响 3 把子功能组合起来 能否达到预期的主功能要求 4 单个模块的误差累积起来是否会放大到不能接受的程度 5 全局数据结构是否有问题 将各个模块组装成系统的方法 非增殖式组装方式和增殖式组装方式 采用非增殖式组装方式 先分别对每个模块进行测试 再把所有模块按设计要求组装在一起进行测试 最终得到所要求的软件 采用增殖式组装方式 把下一个要测试的模块同已经测试好的那些模块结合起来进行测试 测试完以后再把下一个应该测试的模块结合进来测试 这种方法实际上同时完成单元测试和集成测试 这两种方法各有优缺点 1 采用非增殖式组装方式时 可以较早发现模块间的接口错误 而采用增殖式组装方式时 只有在模块加进来时才可能发现 因此接口错误发现较晚 2 采用非增殖式组装方式时要对每个模块进行单元测试 需要编写的测试软件较多 工作量大 而采用增殖式组装方式时 利用已测试过的模块部分作为部分测试软件 因而工作量较小 3 非增殖式组装方式要求一下子把所有模块组装起来 如果发现错误则较难判断错误的位置 而采用增殖式组装方式时 由于每次只加入一个模块 因而错误往往与刚加入的模块有关 查错则相对容易些 4 采用非增殖式组装方式时 各模块的单元测试可以并行地进行 因此可以充分利用人力 加快测试进程 采用增殖式组装方式时却不能如此 1 自顶向下结合 在使用增殖式组装方式时 常用的有自顶向下和自底向上两种方法 采用这种组装方式时 是从主控制模块开始 沿着软件的控制层次向下移动 从而逐渐把各个模块都结合起来 左图是一个树形结构 主控制模块是M1 在把主控制模块M1所属的那些模块都组装起来时可以采取两种方法 深度优先策略或者宽度优先策略 采用深度优先的结合方法时 先把软件结构的一条主控制通路上的所有模块一个一个地结合组装起来 主控制通路的选择取决于应用的特点 对于图8 5来说 如果选取左通路为主控通路 那么首先结合模块M1 M2和M5 然后是M8 如果M2的某个功能需要的话 可结合M6 然后结合中间的和右边的控制通路 采用宽度优先的结合方法时 逐层结合直接下属的所有模块 即把处于同一个控制层次上的所有模块组装起来 对于图8 5来说 首先结合模块M2 M3和M4 代替存根模块S4 接着结合下一个控制层次中的模块M5 M6和M7 如此继续进行下去 直到所有模块都被结合进来 不管是采用深度优先策略还是宽度优先策略 其结合过程如下 1 用主控制模块作为测试驱动模块 所有直接下属于主控制模块的模块用存根模块代替 对主模块进行测试 2 根据选定的结合策略 深度优先或宽度优先 每次用一个实际模块替换一个存根模块 对新结合进来的模块的直接下属模块 用新的存根模块代替 3 对结合进来的模块进行相应的测试 4 为了保证新加入的模块不引入新的错误 可以进行回归测试 即重复以前进行过的部分测试或全部测试 从第 2 步开始 不断地重复进行上述过程 直到所有模块都结合进来为止 采用自顶向下的结合策略的好处 在测试过程中能够较早地对主要的控制或关键的判断点进行检验 因为在一个功能划分合理的软件结构中 关键的判断点常常出现在较高的层次里 所以能够较早碰到 如果主要控制存在问题 及早发现这类问题并尽快想办法解决是十分重要的 这样可以大大减少后面的工作量 如果选择的是深度优先结合方法 可以首先实现并验证软件的一个比较完整的功能 这样对增强开发人员和用户双方的信心是很有意义的 采用自顶向下的结合策略的不足 可能会遇到逻辑上的问题 当我们为了充分地测试较高层次的功能时 可能需要较低层次上处理的信息 但是我们采用自顶向下的方法时 存根模块代替了低层次的模块 若高层模块需要低层模块返回的信息不仅数量大 而且种类也很多时 存根模块有可能很难完全满足这个要求 因而 这种方法有一定的局限性 为了解决这个问题 可以采用以下解决办法 1 把许多测试推迟到用实际模块替换了存根模块以后再进行 采用这种方法也有一定的缺陷 由于我们对一些特定的测试和组装与特定模块间的对应关系失去了某些控制 从而在确定错误原因时会发生困难 2 由层次系统的底部向上组装软件 这种方法就是下面要介绍的自底向上结合方法 2 自底向上结合 自底向上测试是从软件结构最低层的模块开始进行组装和测试 它不需要存根模块 但需要驱动模块 其结合过程如下 1 把低层模块组合成实现某个特定软件子功能的模块族 2 为每一个族编写一个驱动模块 作为测试的控制来协调测试用例的输入和输出 3 对模块族进行测试 4 按模块结构图依次向上扩展 用实际模块替换驱动模块 将模块族与新的模块结合 形成新的模块族 再进行测试 直到所有模块都被结合进来 图中自底向上的结合过程 首先把模块组合成族1 族2和族3 然后设计相应的驱动模块D1 D2和D3 并对每个子功能族进行测试 族1和族2下属于模块Ma 去掉驱动模块D1和D2 把这两个族直接与Ma结合 同样地 在族3与模块Mb结合之前将D3去掉 最后Ma和Mb与Mc结合起来 自顶向下结合的主要优点 不需要设计测试驱动模块 与存根模块相联系的问题可能在测试的早期发现 主要缺点是 需要设计存根模块 并且由于为了使存根模块能够尽量模拟实际模块的功能 必然会增加设计存根模块的复杂度 从而导致增加一些附加的测试 自底向上结合的主要优点 不需要设计存根模块 而设计测试驱动模块一般比建立存根模块要容易 同时比较容易设计测试用例 并且可以实现多个模块的并行测试 从而提高测试效率 主要缺点是 直到最后一个模块结合进来以前 程序作为一个整体始终不存在 也就是说 对主要的控制直到最后才接触到 一般来说 通常根据情况结合这两种方法来进行组装和测试 对软件结构中较上层模块使用自顶向下结合方法 对软件结构中较下层模块使用自底向上结合方法 7 5确认测试 确认测试也称为验收测试 它的目标是验证软件的有效性 软件有效性的一个简单定义是 如果软件的功能和性能如同用户所合理期待的那样 软件就是有效的 需求分析阶段产生的软件需求规格说明书 准确地描述了用户对软件的合理期望 因此是软件有效性的标准 也是进行确认测试的基础 有效性测试 有效性测试的任务 进一步验证软件的有效性 即验证软件的功能和性能是否与用户的要求一致 在每个有效性测试用例测试完成以后 可能有两种情况 1 软件的功能和性能与用户的要求一致 软件可以接受 2 软件的功能或性能与用户的要求有差距 若出现后一种情况 通常与需求分析阶段的差错有关 这时要列出一张软件缺陷表 通过与用户的协商 找出问题所在并解决它 系统测试 软件仅仅是计算机系统的一个组成部分 在实际运行中 它要和计算机系统的其它元素一起工作 所以最终要把软件与其它系统元素结合起来 进行一系列的集成测试和有效性测试 系统测试的目的在于通过与系统的需求定义作比较 发现软件与系统定义不符合或与之矛盾的地方 任何产品都可以使用以下两种方法进行测试 1 如果已知产品的功能 则可以对它的每一个功能进行测试 看是否都达到了预期的要求 2 如果已知产品的内部工作过程 则可以对它的每种内部操作进行测试 看是否符合设计要求 第一种方法是黑盒测试 第二种方法是白盒测试 软件测试方法 白盒测试时将程序看作是一个透明的盒子 也就是说测试人员完全了解程序的内部结构和处理过程 所以测试时按照程序内部的逻辑测试程序 检验程序中的每条通路是否都能按预定的要求正确工作 白盒测试又称为结构测试 7 6白盒测试 利用白盒测试设计测试用例时 应包括以下三类测试 1 语句测试 要求程序中的每个语句至少测试一次 2 分支测试 要求程序中的每个分支至少测试一次 3 路径测试 要求程序中的每条路径至少测试一次 白盒测试也不能实现穷尽测试 左图所示的一个小程序的控制流程 其中每个圆圈代表一段源程序 或语句块 图中的曲线代表执行次数不超过20的循环 循环体中共有5条通路 这样 可能执行的路径有520条 近似为1014条可能的路径 如果完成一个路径的测试需要1毫秒 那么整个测试过程需要3170年 显然 这也是不能接受的 逻辑覆盖是以程序的内部逻辑结构为基础的测试用例设计技术 属于白盒测试 它要求测试人员十分清楚程序的逻辑结构 考虑的是测试用例对程序内部逻辑覆盖的程度 根据覆盖的目标 逻辑覆盖又可以分为 语句覆盖判定覆盖条件覆盖判定 条件覆盖条件组合覆盖 7 6 1逻辑覆盖 点覆盖边覆盖路径覆盖 1 语句覆盖 语句覆盖就是设计足够的调试用例 使得程序中的每个语句至少执行一次 左图程序段中共有4条路径 P1 ace P2 abd P3 abe P4 acd 语句覆盖不能发现判断中的逻辑运算中的错误 第一个判断中的逻辑运算符 若错写成了 利用上面的输入数据则检查不出这个错误 P1正好满足语句覆盖的条件 可以设计如下的输入数据 A 2 B 0 x 4 2 判定覆盖 判定覆盖就是设计足够的测试用例 使得程序中每个判定的取 真 分支和取 假 分支至少都执行一次 判定覆盖又称分支覆盖 测试用例如果能够测试路径P1 ace 和P2 abd 就可以满足判定覆盖要求 可以设计如下两组输入数据 A 2 B 0 x 4A 1 B 1 x 1也可以让测试用例测试路径P3 abe 和P4 acd 相应的两组输入数据如下 A 2 B 1 x 1A 4 B 0 x 4判定覆盖比语句覆盖强 但是仍不能保证判断条件的正确性 例如 第二个判断条件中的x 1若错写成了x 1 利用上面的输入数据就不能检查出这个错误 3 条件覆盖 条件覆盖就是设计足够的测试用例 使得程序判定中的每个条件能获得各种可能的结果 条件 A 1 B 0 A 2 x 1 需要有足够的测试用例使得上述四个条件都能有满足和不满足的情况 以下这两组输入数据能满足这些要求 A 2 B 0 x 4A 1 B 1 x 1这两组数据不仅满足条件覆盖的要求 而且也满足判定覆盖的要求 但并不是所有的满足条件覆盖要求的数据都满足判定覆盖的要求 例 A 1 B 0 x 3A 2 B 1 x 1 这组数据满足条件覆盖的要求 不满足判定覆盖的要求 4 判定 条件覆盖 判定 条件覆盖就是设计足够的测试用例 使得判定中的每个条件都取到各种可能的值 而且每个判定表达式也都取到各种可能的结果 对于上面的例子 下述两组输入数据能满足这些要求 A 2 B 0 x 4A 1 B 1 x 1判定 条件覆盖仍有缺陷 从表面上看 它测试了所有条件的所有可能结果 但事实上并不是这样 因为某些条件掩盖了另一些条件 例如 在逻辑表达式中 如果 与 表达式中某一条件为 假 则整个表达式的值为 假 这个表达式中另外的几个条件就不起作用了 同样地 如果在 或 表达式中 某一条件为 真 则整个表达式的值为 真 其它条件也就不起作用了 因此 采用判定 条件覆盖时 逻辑表达式中的错误不一定能测试出来 5 条件组合覆盖 条件组合覆盖就是设计足够的测试用例 使得每个判定中的条件的各种可能组合都至少出现一次 可能的条件组合 1 A 1 B 0 2 A 1 B 0 3 A 1 B 0 4 A 1 B 0 5 A 2 x 1 6 A 2 x 1 7 A 2 x 1 8 A 2 x 1 相应的输入数据 A 2 B 0 x 4满足 1 和 5 A 2 B 1 x 1满足 2 和 6 A 1 B 0 x 2满足 3 和 7 A 1 B 1 x 1满足 4 和 8 显然 满足条件组合覆盖的测试数据 也一定满足判定覆盖 条件覆盖和判定 条件覆盖标准 但是 满足条件组合覆盖标准的测试数据并不一定覆盖了程序中的每条路径 例如 利用上述四组测试数据就遗漏了路径P4 acd 6 点覆盖图论中点覆盖的概念定义如下 如果连通图G的子图G 是连通的 而且包含G的所有结点 则称G 是G的点覆盖 满足点覆盖标准要求选取足够多的测试数据 使得程序执行路径至少经过流图的每个结点一次 由于流图的每个结点与一条或多条语句相对应 显然点覆盖标准和语句覆盖标准是相同的 7 边覆盖图论中边覆盖的定义是 如果连通图G的子图G 是连通的 而且包含G的所有边 则称G 是G的边覆盖 为了满足边覆盖的测试标准 要求选取足够多测试数据 使得程序执行路径至少经过流图中每条边一次 通常边覆盖和判定覆盖是一致的 8 路径覆盖路径覆盖的含义是 选取足够多测试数据 使程序的每条可能路径都至少执行一次 如果程序图中有环 则要求每个环至少经过一次 从程序流程图可导出流图 在正常情况下流图是连通的有向图 7 6 2控制结构测试 1 基本路径测试基本路径测试是一种白盒测试技术 使用这种技术设计测试用例时 首先计算程序的环形复杂度 并用该复杂度为指南定义执行路径的基本集合 从该基本集合导出的测试用例可以保证程序中的每条语句至少执行一次 而且每个条件在执行时都将分别取真 假两种值 7 6 2控制结构测试 1 基本路径测试使用基本路径测试技术设计测试用例的步骤如下 第一步 根据过程设计结果画出相应的流图 例如 为了用基本路径测试技术测试下列的用PDL描述的求平均值过程 首先画出图7 6所示的流图 注意 为了正确地画出流图 我们把被映射为流图结点的PDL语句编了序号 PROCEDUREaverage 这个过程计算不超过100个在规定值域内的有效数字的平均值 同时计算有效数字的总和及个数 INTERFACERETURNSaverage total input total valid INTERFACEACCEPTSvalue minimum maximum TYPEvalue 1 100 ISSCALARARRAY TYPEaverage total input total valid minimum maximum sumISSCALAR TYPEiISINTEGER 1 i 1 total input total valid 0 sum 0 2 DOWHILEvalue i 9993 ANDtotal input minimum6 ANDvalue i 011 THENaverage sum total valid 12 ELSEaverage 999 13 ENDIFENDaverage 第二步 计算流图的环形复杂度 环形复杂度定量度量程序的逻辑复杂性 有了描绘程序控制流的流图之后 可以用第6 5 1小节讲述的3种方法之一计算环形复杂度 经计算 图7 6所示流图的环形复杂度为6 图7 6求平均值过程的流图 计算环形复杂度 1 流图中的区域数等于环形复杂度 2 流图G的环形复杂度V G E N 2 其中 E是流图中边的条数 N是结点数 3 流图G的环形复杂度V G P 1 其中 P是流图中判定结点的数目 第三步 确定线性独立路径的基本集合 所谓独立路径是指至少引入程序的一个新处理语句集合或一个新条件的路径 用流图术语描述 独立路径至少包含一条在定义该路径之前不曾用过的边 使用基本路径测试法设计测试用例时 程序的环形复杂度决定了程序中独立路径的数量 而且这个数是确保程序中所有语句至少被执行一次所需的测试数量的上界 对于图7 6所描述的求平均值过程来说 由于环形复杂度为6 因此共有6条独立路径 通常在设计测试用例时 识别出判定结点是很有必要的 本例中结点2 3 5 6和10是判定结点 第四步 设计可强制执行基本集合中每条路径的测试用例 应该选取测试数据使得在测试每条路径时都适当地设置好了各个判定结点的条件 在测试过程中 执行每个测试用例并把实际输出结果与预期结果相比较 一旦执行完所有测试用例 就可以确保程序中所有语句都至少被执行了一次 而且每个条件都分别取过true值和false值 应该注意 某些独立路径不能以独立的方式测试 也就是说 程序的正常流程不能形成独立执行该路径所需要的数据组合 在这种情况下 这些路径必须作为另一个路径的一部分来测试 2 条件测试用条件测试技术设计出的测试用例 能够检查程序模块中包含的逻辑条件 一个简单条件是一个布尔变量或一个关系表达式 在布尔变量或关系表达式之前还可能有一个NOT算符 关系表达式的形式如下 E1E2其中 E1和E2是算术表达式 而是下列算符之一 或 复合条件由两个或多个简单条件 布尔算符和括弧组成 布尔算符有OR AND 和NOT 不包含关系表达式的条件称为布尔表达式 因此 条件成分的类型包括布尔算符 布尔变量 布尔括弧 括住简单条件或复合条件 关系算符及算术表达式 条件测试方法着重测试程序中的每个条件 本节下面将讲述的条件测试策略有两个优点 容易度量条件的测试覆盖率 程序内条件的测试覆盖率可指导附加测试的设计 人们已经提出了许多条件测试策略 分支测试可能是最简单的条件测试策略 对于复合条件C来说 C的真分支和假分支以及C中的每个简单条件 都应该至少执行一次 包含n个变量的布尔表达式需要2n个 每个变量分别取真或假这两个可能值的组合数 测试 这个策略可以发现布尔算符 变量和括弧的错误 但是 该策略仅在n很小时才是实用的 BRO branchandrelationaloperator 测试 如果在条件中所有布尔变量和关系算符都只出现一次而且没有公共变量 则BRO测试保证能发现该条件中的分支错和关系算符错 BRO测试利用条件C的条件约束来设计测试用例 包含n个简单条件的条件C的条件约束定义为 D1 D2 Dn 其中Di 0 和 指定表达式的输出约束 3 循环测试循环测试是一种白盒测试技术 它专注于测试循环结构的有效性 在结构化的程序中通常只有3种循环 即简单循环 串接循环和嵌套循环 如图7 7所示 图7 73种循环 1 简单循环 应该使用下列测试集来测试简单循环 其中n是允许通过循环的最大次数 跳过循环 只通过循环一次 通过循环两次 通过循环m次 其中m n 1 通过循环n 1 n n 1次 2 嵌套循环 从最内层循环开始测试 把所有其他循环都设置为最小值 对最内层循环使用简单循环测试方法 而使外层循环的迭代参数 例如 循环计数器 取最小值 并为越界值或非法值增加一些额外的测试 由内向外 对下一个循环进行测试 但保持所有其他外层循环为最小值 其他嵌套循环为 典型 值 继续进行下去 直到测试完所有循环 3 串接循环 如果串接循环的各个循环都彼此独立 则可以使用前述的测试简单循环的方法来测试串接循环 但是 如果两个循环串接 而且第一个循环的循环计数器值是第二个循环的初始值 则这两个循环并不是独立的 当循环不独立时 建议使用测试嵌套循环的方法来测试串接循环 黑盒测试时完全不考虑程序内部的结构和处理过程 只按照规格说明书的规定来检查程序是否符合它的功能要求 黑盒测试是在程序接口进行的测试 又称为功能测试 黑盒测试检查的主要方面有 程序的功能是否正确或完善 数据的输入能否正确接收 输出是否正确 是否能保证外部信息 如数据文件 的完整性等 用黑盒法设计测试用例时 必须用所有可能的输入数据来检查程序是否都能产生正确的输出 7 7黑盒测试 黑盒测试不可能实现穷尽测试 假设有一个很简单的小程序 输入量只有两个 A和B 输出量只有一个 C 如果计算机的字长为32位 A和B的数据类型都只是整数类型 利用黑盒法进行测试时 将A和B的可能取值进行排列组合 输入数据的可能性有 232 232 264种 假设这个程序执行一次需要1毫秒 要完成所有的测试 计算机需要连续工作5亿年 显然 这是不能容忍的 而且 设计测试用例时 不仅要有合法的输入 而且还应该有非法的输入 在这个例子中 输入还应该包括实数 字符串等 这样 输入数据的可能性就更多了 所以说 穷尽测试是不可能实现的 7 1 1等价类划分 等价类划分是一种实用的测试技术 属于黑盒测试 与逻辑覆盖不同 使用等价类划分设计测试用例时 完全不需要考虑程序的内部逻辑结构 而主要依据程序的功能说明 穷尽测试是不可能实现的 实际上也是不必要的 我们可以从所有可能的输入数据中选择一个子集来进行测试 如何选择这个子集 使得这个子集具有代表性 能尽可能多地发现程序中的错误 等价类划分就是基于这种考虑的一种实现方法 该方法根据输入数据和输出数据的特点 将程序输入域划分成若干个部分 即子集 然后从每个子集中选取具有代表性的数据作为测试用例 1 划分等价类 等价类的划分在很大程度上依靠的是测试人员的经验 下面给出几条基本原则 1 如果输入条件规定了取值范围 则可划分出一个有效的等价类 输入值在此范围内 和两个无效的等价类 输入值小于最小值 输入值大于最大值 2 如果输入条件规定了输入数据的个数 则可相应地划分出一个有效的等价类 输入数据的个数等于给定的个数要求 和两个无效的等价类 输入数据的个数少于给定的个数要求 输入数据的个数多于给定的个数要求 3 如果输入条件规定了输入数据的一组可能的值 而且程序对这组可能的值做相同的处理 则可将这组可能的值划分为一个有效的等价类 而这些值以外的值划分成无效的等价类 4 如果输入条件规定了输入数据的一组可能的值 但是程序对不同的输入值做不同的处理 则每个输入值是一个有效的等价类 此外还有一个无效的等价类 所有不允许值的集合 5 如果输入条件规定了输入数据必须遵循的规则 则可以划分一个有效的等价类 符合规则 和若干个无效的等价类 从各种角度违反规则 6 如果程序的处理对象是表格 则应该使用空表 以及含一项或多项的表 2 选择测试用例 划分出等价类后 根据以下原则设计测试用例 1 为每个等价类编号 2 设计一个新的测试用例 使它能包含尽可能多的尚未被覆盖的有效等价类 重复这一过程 直到所有的有效等价类都被覆盖 3 设计一个新的测试用例 使它包含一个尚未被覆盖的无效等价类 重复这一过程 直到所有的无效等价类都被覆盖 假设有一个把数字串转变成整数的函数 运行程序的计算机字长16位 用二进制补码表示整数 这个函数是用Pascal语言编写的 它的说明如下 functionstrtoint dstr shortstr integer 函数的参数类型是shortstr 它的说明是 typeshortstr array 1 6 ofchar 被处理的数字串是右对齐的 也就是说 如果数字串比6个字符短 则在它的左边补空格 如果数字串是负的 则负号和最高位数字紧相邻 负号在最高位数字左边一位 考虑到Pascal编译程序固有的检错功能 测试时不需要使用长度不等于6的数组做实在参数 更不需要使用任何非字符数组类型的实在参数 分析这个程序的规格说明 可以划分出如下等价类 有效输入的等价类有 1 1 6个数字字符组成的数字串 最高位数字不是零 2 最高位数字是零的数字串 3 最高位数字左邻是负号的数字串 无效输入的等价类有 4 空字符串 全是空格 5 左部填充的字符既不是零也不是空格 6 最高位数字右面由数字和空格混合组成 7 最高位数字右面由数字和其他字符混合组成 8 负号与最高位数字之间有空格 合法输出的等价类有 9 在计算机能表示的最小负整数和零之间的负整数 10 零 11 在零和计算机能表示的最大正整数之间的正整数 非法输出的等价类有 12 比计算机能表示的最小负整数还小的负整数 13 比计算机能表示的最大正整数还大的正整数 因为所用的计算机字长16位 用二进制补码表示整数 所以能表示的最小负整数是 32768 能表示的最大正整数是32767 P164 P165 7 7 2边界值分析 使用边界值分析方法设计测试用例时 首先要确定边界情况 通常输入等价类和输出等价类的边界 就是应该着重测试的程序边界情况 也就是说 应该选取恰好等于 小于和大于边界的值作为测试数据 而不是选取每个等价类内的典型值或任意值作为测试数据 边界值分析也属于黑盒测试 可以看作是对等价类划分的一个补充 在设计测试用例时 往往联合等价类划分和边界值分析这两种方法 P165 7 7 3错误推测法 错误推测法的基本想法是 列举出程序中所有可能有的错误和容易发生错误的特殊情况 根据它们选择测试用例 例如 输入数据为零或输出数据为零的地方往往容易出错 各模块间对公有变量的引用也是容易出错的地方 例 程序TRIANGLE输入三个整数 他们表示一个三角形的三条边 该程序产生一个结果指出该三角形是等腰三角形 等边三角形还有不等边三角形 所选测试用例应包含下列情况 1 合理的不等边三角形 输入数据为1 2 3或2 5 10等不能算这一类 2 合理的等边三角形 输入数据为0 0 0等不能算这一类 3 合理的等腰三角形 输入数据为2 2 4等不能算这一类 4 等腰三角形的三种排列次序 如3 3 4 3 4 3和4 3 3等 5 三个正数 其中两个之和等于第三个 6 第5种情况的三种排列次序 如1 2 3 1 3 2和3 1 2等 7 三个正数 其中两个之和小于第三个 8 第7种情况的三种排列次序 如1 2 4 1 4 2 和4 1 2等 9 输入数据含有零值10 输入数据含有负值11 输入数据含有非整数值12 三个数均为零13 数据数据不是三个数 如只有两个输入数 等价分类法1 划分等价类2 选择测试用例从每个等价类中只取一组数值作为测试数据 这样选取的测试数据最有代表性 例 2 合理的等边三角形对于程序TRIANGLE来说 它的某一个 等价类 可以是 大于零的三个等值数 如果这个等价类中的某一例子 如a b c 4 没有发现错误 那么这一等价类的其他例子 如a b c 10 a b c 256 等 也不会发现错误 我们就可以把精力转移到其他等价类 等价分类和边界值分析的联合运用程序TRIANGLE的功能说明中指出了 三个数据数据表示一个三角形的三条边长 所以其中任意两个边之和应大于第三个 不仅要选用合理的输入数据作为测试用例 还应该选用不合理的输入数据作为测试用例 如果采用等价分类法 我们至少可找出两个等价类 两个输入数之和大于第三个的合理等价类 测试用例 a 3 b 4 c 5两个输入数之和不大于第三个的不合理等价类 测试用例 a 1 b 2 c 4如果程序中将表达式a b c错误地写成a b c 上述两个例子是不能发现这一错误的 而采用边缘值分析法 则会选择例子 a 1 b 2 c 3从而使上述错误暴露出来 所以等价分类法与边缘分析法的主要差别在于 后者是着重检查等价边界上的情况 7 8 1调试过程 7 8调试 调试过程由两个部分组成 首先 确定程序中错误的确切性质和位置 然后 对程序代码进行分析 确定问题的原因 并设法改正这个错误 具体地说 由以下步骤组成 1 从错误的外部表现入手 确定程序中出错的位置 2 分析有关程序代码 找出错误的内在原因 3 修改程序代码 排除这个错误 4 重复进行暴露了这个错误的原始测试以及某些回归测试 以确保该错误确实被排除且没有引入新的错误 5 如果所作的修正无效 则撤消这次改动 重复上述过程 直到找到一个有效的办法为止 调试的步骤 7 8 2调试途径 1 蛮干法 2 回溯法 3 原因排除法 1 对分查找法 2 归纳法 3 演绎法 软件可靠性可以根据与技术系统可靠性接近的平行定义来表示 我们可以这样来定义软件可靠性 程序故障的频率和临界值 这里 故障是指在许可的运行条件下一个不可接受的结果或行为 同硬件一样 软件可靠性可以用错误出现和被纠正的速率来表示 7 9 1基本概念 1 软件可靠性的定义软件可靠性是程序在给定的时间间隔内 按照规格说明书的规定成功地运行的概率 硬件可靠性可以用平均故障间隔时间 MTBF 来测量 MTBF MTTF十MTTR其中 MTTF和MTTR分别是平均无故障时间和平均修复时间 7 9软件可靠性 2 软件的可用性软件可用性是程序在给定的时间点 按照规格说明书的规定 成功地运行的概率 可靠性和可用性之间的主要差别是 可靠性意味着在0到t这段时间间隔内系统没有失效 而可用性只意味着在时刻t 系统是正常运行的 因此 如果在时刻t系统是可用的 则有下述种种可能 在0到t这段时间内 系统一直没失效 可靠 在这段时间内失效了一次 但是又修复了 在这段时间内失效了两次修复了两次 如果在一段时间内 软件系统故障停机时间分别为td1 td2 正常运行时间分别为tu1 tu2 则系统的稳态可用性为 Ass Tup Tup Tdown 7 1 其中Tup tui Tdown tdi 如果引入系统平均无故障时间MTTF和平均维修时间MTTR的概念 则 7 1 式可以变成Ass MTTF MTTF MTTR 7 2 平均维修时间MTTR是修复一个故障平均需要用的时间 它取决于维护人员的技术水平和对系统的熟悉程度 也和系统的可维护性有重要关系 第8章将讨论软件维护问题 平均无故障时间MTTF是系统按规格说明书规定成功地运行的平均时间 它主要取决于系统中潜伏的错误的数目 因此和测试的关系十分密切 软件的平均无故障时间MTTF是一个重要的质量指标 往往作为对软件的一项要求 由用户提出来 为了估算MTTF 首先引入一些有关的量 1 符号在估算MTTF的过程中使用下述符号表示有关的数量 ET 测试之前程序中错误总数 IT 程序长度 机器指令总数 测试 包括调试 时间 Ed 在0至 期间发现的错误数 Ec 在0至 期间改正的错误数 7 9 2估算平均无故障时间的方法 2 基本假定 1 在类似的程序中 单位长度里的错误数ET IT近似为常数 美国的一些统计数字表明 通常0 5 10 2 ET IT 2 10 2也就是说 在测试之前每1000条指令中大约有5 20个错误 2 失效率正比于软件中剩余的 潜藏的 错误数 而平均无故障时间MTTF与剩余的错误数成反比 3 为了简化讨论 假设发现的每一个错误都立即正确地改正了 即 调试过程没有引入新的错误 因此Ec Ed 剩余的错误数为Er ET Ec 7 3 单位长度程序中剩余的错误数为 r ET Ir Ec IT 7 4 3 估算平均无故障时间经验表明 平均无故障时间与单位长度程序中剩余的错误数成反比 即MTTF 1 K ET IT Ec IT 7 5 其中K为常数 它的值应该根据经验选取 美国的一些统计数字表明 K的典型值是200 估算平均无故障时间的公式 可以评价软件测试的进展情况 此外 由 7 5 式可得Ec ET IT K MTTF 7 6 因此 也可以根据对软件平均无故障时间的要求 估计需要改正多少个错误之后 测试工作才能结束 4 估计错误总数的方法 1 植入错误法使用这种估计方法 在测试之前由专人在程序中随机地植入一些错误 测试之后 根据测试小组发现的错误中原有的和植入的两种错误的比例 来估计程序中原有错误的总数ET 假设人为地植入的错误数为Ns 经过一段时间的测试之后发现ns个植入的错误 此外还发现了n个原有的错误 如果可以认为测试方案发现植入错误和发现原有错误的能力相同 则能够估计出程序中原有错误的总数为N n ns Ns 7 7 其中N 即是错误总数ET的估计值 2 分别测试法为了随机地给一部分错误加标记 分别测试法使用两个测试员 或测试小组 彼此独立地测试同一个程序的两个副本 把其中一个测试员发现的错误作为有标记的错误 具体做法是 在测试过程的早期阶段 由测试员甲和测试员乙分别测试同一个程序的两个副本 由另一名分析员分析他们的测试结果 用 表示测试时间 假设 0时错误总数为B0 1时测试员甲发现的错误数为B1 1时测试员乙发现的错误数为B2 1时两个测试员发现的相同错误数为bc 如果认为测试员甲发现的错误是有标记的 即程序中有标记的错误总数为B1 则测试员乙发现的B2个错误中有bc个是有标记的 假定测试员乙发现有标记错误和发现无标记错误的概率相同 则可以估计出测试前程序中的错误总数为B0 B2 bcB1 7 8 程序正确性证明是一项复杂的课题 涉及到许多复杂的领域 采用诸如利用数学归纳法或谓词演算的人工的正确性证明 在评价小程序时可能有些价值 但是在证明大型软件的正确性时 不仅工作量太大 而且在证明的过程中也很容易引进一些新的错误 因此并不实用 目前 已经开发出了一些自动的计算机软件正确性证明方法 自动的正确性证明程序一般涉及到程序逻辑的形式化描述 这种描述可以由宏编译程序来开发 宏编译程序产生软件的符号表示 利用以人工智能理论和谓词演算为基础的自动化技术来 证明 程序的正确性 目前已经研究出了PASCAL和LISP等的正确性证明程序 正在对这些系统进行评价和改进 这些系统目前还只能对较小的程序进行评价 程序正确性证明
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!