• 通常将编码和测试统称为实现。

7.1 编码

  1. 编码的定义
    • 编码是把软件设计结果翻译成用程序设计语言书写的程序。
  2. 效率
    • 效率主要指处理机时间和存储器容量两个方面。

7.2 软件测试基础

  • 软件测试的定义
    • 测试是为了发现程序中的错误而执行程序的过程。
  • 测试的目的:
    • 在软件投入生产性运行前,尽可能多地发现软件中的错误。
  • 测试的根本任务:发现并改正软件中的错误。
  • 根本目标是尽可能多地发现并排除软件中潜藏的错误,最终把一个高质量的软件系统交给用户使用。
  • 大型软件测试分为单元测试、集成测试和验收测试。

7.2.1 软件测试的目标

  • (1)测试是为了发现程序中的错误而执行程序的过程。
  • (2)好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案。
  • (3)成功的测试是发现了至今为止尚未发现的错误的测试。
  • 【注意】测试只能查找出程序中的错误,不能证明程序中没有错误。测试的目标是发现错误,调试的任务是在测试的基础上去改正错误。

7.2.2 软件测试的准则

  • ① 所有的测试都可以追溯至用户需求;
  • ② 测试开始之前就制定测试计划;
  • ③ 把Pareto原理应用到软件测试中(测试发现的80%很可能是由程序中的20%的模块造成的,怎样找出这些可疑的模块);
  • ④ 从“小规模”测试开始,逐步进行“大规模”测试;
  • ⑤ 避免穷举测试(把执行路径都检查一遍,不可能做到,执行路径非常庞大);
  • ⑥ 由独立的第三方从事测试工作以达到最佳的测试效果。

7.2.3 测试方法

  • (1)白盒测试
    • ① 白盒测试(结构测试,已经知道产品的内部工作过程)把程序看成装在一个透明的白盒子里,测试者完全知道程序的结构和处理算法。
    • ② 按照程序内部的逻辑测试程序,检测程序中的主要执行通路是否都能按预定要求正确工作。
  • (2)黑盒测试
    • ① 黑盒测试(功能测试,已经知道产品应该具有的功能)把程序看作一个黑盒子,完全不考虑程序的内部结构和处理过程。
    • ② 黑盒测试是在程序接口进行的测试,只检查程序功能是否能按照规格说明书的规定正常使用。

7.2.4 测试步骤

  • (1)单元测试(模块测试)
    • ① 定义:单元测试把每个模块作为一个单独的实体来测试,检验其正确性。
    • ② 目的:保证每个模块作为一个单元能正确运行。
    • 【注意】单元测试发现的是编码和详细设计的错误。
  • (2)子系统测试
    • ① 定义:子系统测试把经过单元测试的模块放在一起形成一个子系统来测试。
    • ② 目的:着重测试模块的接口。
  • (3)系统测试
    • ① 定义:系统测试是把经过测试的子系统装配成一个完整的系统来测试。
    • ② 目的:发现设计和编码的错误,并验证系统确实能提供需求说明书中指定的功能。
    • 【注意】子系统测试和系统测试都属于集成测试。
  • (4)验收测试(确认测试)
    • ① 定义:在用户的参与下,把软件系统作为单一的实体,使用实际数据进行测试。
    • ② 目的:验证系统确实能够满足用户的需要。
    • 【注意】验收测试发现的是系统需求说明书中的错误。
  • (5)平行运行
    • ① 定义:同时运行新开发出来的系统和将被它取代的旧系统,以便比较两个系统的处理结果
    • ② 目的:
      • 可以在准生产环境中运行新系统而不冒风险
      • 用户可以有一段熟悉新系统的时间
      • 可以验证用户指南和使用手册之类的文档
      • 能够以准生产模式对新系统进行全负荷测试,可以用测试结果验证性能指标

7.2.5 测试阶段的信息流

  • 这个阶段的输入信息有:
    • 软件配置,包括需求说明书、设计说明书、源程序清单
    • 测试配置,包括测试计划、测试方案
  • 在这里插入图片描述

7.3 单元测试(模块测试)

  • 单元测试:检测软件设计的最小单元——模块
  • 单元测试主要使用白盒测试技术。
  • 1.测试重点
    • 着重从下面5个方面对模块进行单元测试
    • (1)模块接口;
    • (2)局部数据结构;
    • (3)重要的执行通路;
    • (4)出错处理通路;
    • (5)边界条件。
  • 2.测试方法
    • (1)代码审查;
    • (2)计算机测试。
    • 计算机测试和人工测试(代码审查)各有优缺点互相补充,缺一不可。
  • 【注意】必须要为每个单元测试开发驱动软件和(或)存根软件。

7.4 集成测试

  • 集成测试定义:
    • 测试和组装软件的系统化技术
    • 在单元测试的基础上,将所有模块按照设计要求组装成为子系统或系统,进行集成测试。
    • 子系统测试把模块按照设计要求组装起来的同时进行测试
    • 主要目标是发现与接口有关的问题。
  • 概念
    • (1)模块组装成程序的方法分类
      • ① 非渐增式测试:单独测试每个模块,最后合并所有模块进行测试。
      • ② 渐增式测试:每次测试增加一个模块。
    • (2)非渐增式测试的缺点
      • ① 把所有模块放在一起,测试者面对的情况十分复杂。
      • ② 在庞大的程序中诊断定位一个错误非常困难。
      • ③ 一旦改正一个错误之后,又会遇到新的错误,没有穷尽。
    • (3)渐增式测试的优点
      • ① 把程序划分成小段来构造和测试,比较容易定位和改正错误。
      • ② 对接口可以进行更彻底的测试。
      • ③ 可以使用系统化的测试方法。
  • 渐增式测试的策略
    • (1)自顶向下集成
      • 从主控制模块(根结点)开始,沿着程序的控制层次向下移动,逐渐把各个模块结合起来,在集成过程中,可以采用宽度优先或深度优先的策略向下推进
      • 包含深度优先和宽度优先两种结合策略。
    • (2)自底向上集成
      • 从“原子”模块开始组装和测试,不需要存根,需要驱动程序
  • 两种集成策略的比较
    • (1)自顶向下集成
      • ① 优点
        • a.不需要测试驱动程序。
        • b.能够在测试阶段的早期实现并验证系统的主要功能。
        • c.能在早期发现上层模块的接口错误。
      • ② 缺点
        • a.需要存根程序,可能遇到与此相联系的测试困难。
        • b.低层关键模块中的错误发现较晚。
        • c.在早期不能充分展开人力。
    • (2)自底向上集成
      • ① 优点
        • a.不需要存根程序,不会遇到与存根程序相联系的测试困难。
        • b.能较早的发现低层关键模块的错误。
        • c.能在早期充分展开人力。
      • ② 缺点
        • a.需要测试驱动程序。
        • b.不能在测试阶段早期实现并验证系统的主要功能。
        • c.在早期不能发现上层模块的接口错误。
  • 其他集成测试策略
    • (1)改进的自顶向下测试方法;
    • (2)混合法。
  • 回归测试
    • (1)定义
      • 回归测试是指重新执行已经做过的测试的某个子集,以保证上述这些变化没有带来非预期的副作用。
    • (2)目的
      • 保证由于调试或其他原因引起的变化,不会导致非预期的软件行为或额外错误的测试活动。
    • (3)回归测试集测试用例:
      • ①检测软件全部功能的代表性测试用例;
      • ②专门针对可能受修改影响的软件功能的附加测试;
      • ③针对被修改过的软件成分的测试。

7.5 确认测试(验收测试)

  • 确认测试,也称为验收测试,用户根据需求说明书进行测试
  • 验收测试由最终用户而不是系统的开发者进行。
  • 目标:验证软件的有效性
  • 确认测试通常使用黑盒测试法。
  • 确认测试的重要内容:软件配置复查
  • 确认测试分为Alpha测试和Beta测试。
    • Alpha测试:受控制环境下进行
    • Beta测试:不受控制环境下进行

7.6 白盒测试技术

  • 设计测试方案是测试阶段的关键技术问题
    • 测试方案包括具体的测试目的,应该输入的测试数据和预期的结果
    • 设计测试方案的目的:确定一组最可能发现某个错误或某类错误的测试数据
  • 白盒测试主要使用于早期阶段;
  • 设计白盒测试方案的技术主要有
    • 逻辑覆盖,也称为通路测试,有语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖、路径覆盖
    • 控制结构测试,基本路径测试和条件测试
  • 逻辑覆盖
    • 一组参数过程逐渐进行越来越完整的通路测试
    • ① 语句覆盖
      • 语句覆盖的含义是选择足够多的测试数据,使被测程序中每个语句至少执行一次。
    • ② 判定覆盖(分支覆盖)
      • 判定覆盖的含义是不仅每个语句必须至少执行一次,而且每个判定的每种可能的结果都应该至少执行一次。
    • ③ 条件覆盖
      • 条件覆盖的含义是不仅每个语句至少执行一次,而且使判定表达式中的每个条件都取到各种可能的结果。
    • ④ 判定/条件覆盖
      • 判定/条件覆盖的含义是不仅使得判定表达式中的每个条件都取到各种可能的值,而且每个判定表达式也都取到各种可能的结果。它同时满足判定覆盖和条件覆盖。
    • ⑤ 条件组合覆盖
      • 条件组合覆盖要求选取足够多的测试数据,使得每个判定表达式中条件的各种可能组合都至少出现一次。满足条件组合覆盖,也一定满足判定覆盖、条件覆盖和判定/条件覆盖标准。
    • ⑥ 点覆盖
      • 要求选取足够多的测试数据,使得程序执行路径至少经过流图的每个结点一次。
      • 【注意】点覆盖标准和语句覆盖标准是相同的。
    • ⑦ 边覆盖
      • 要求选取足够多测试数据,使程序执行路径至少经过流图中每条边一次。
      • 【注意】边覆盖与判定覆盖是相同的。
    • ⑧ 路径覆盖
      • 路径覆盖含义是选取足够多测试数据,使程序的每条可能路径都至少执行一次,如果程序图中有环,则要求每个环至少经过一次。
  • 控制结构测试
    • (1)基本路径测试
    • 【注意】某些独立路径不能以独立的方式测试,即程序的正常流程不能形成独立执行该路径所需要的数据组合。
    • (2)条件测试
    • (3)循环测试
      • 在结构化的程序中通常只有3种循环,即简单循环、串接循环和嵌套循环。
      • 在这里插入图片描述

7.7 黑盒测试技术

  • 黑盒测试力图发现的错误:
    • ①功能不正确或遗漏了功能;
    • ②界面错误;
    • ③数据结构错误或外部数据库访问错误;
    • ④性能错误;
    • ⑤初始化和终止错误。
  • 黑盒测试主要使用于后期阶段。
  • 设计黑盒测试方案技术主要有,等价划分、边界值分析和错误推测。
  • 等价划分
    • 把程序的输入域划分成若干个数据类,选取每个等价类中的一个典型值或任意值作为测试数据。
  • 边界值分析
    • 确定边界情况,选取刚好等于、稍小于和稍大于等价类边界值的数据作为测试数据。
  • 错误推测
    • 利用判定表或判定树为工具,列出输入数据各种组合与程序应做的动作之间的对应关系,然后为判定表的每一列至少设计一个测试用例。

7.8 调试

  • 定义
    • 调试是在测试发现错误之后排除错误的过程。
    • 调试:定位错误,及时改正错误。
  • 调试途径
    • (1)蛮干法。
    • (2)回溯法。
    • (3)原因排除法。
      • ① 对分查找法;
      • ② 归纳法;
      • ③ 演绎法。
  • 【注意】务必注意测试和调试的区别。改错是调试的任务,测试的任务是发现错误。

7.9 软件可靠性

  • 测试阶段的根本目标是消除错误,保证软件的可靠性
  • 程序中潜藏的错误的数目,直接决定了软件的可靠性
  • 基本概念
    • (1)软件可靠性
      • 软件可靠性是程序在给定的时间间隔内,按照规格说明书的规定成功地运行的概率。
    • (2)软件的可用性
      • 软件可用性是程序在给定的时间点,按照规格说明书的规定,成功地运行的概率。
    • (3)MTTF和MTTR
      • ① 概念
        • a.平均维修时间MTTR
          • 表示修复一个故障平均需要用的时间。
        • b.平均无故障时间MTTF
          • 表示系统按规格说明书规定成功地运行的平均时间。
      • ② 计算公式
        • 如果在一段时间内,软件系统故障停机时间分别为 t d 1 , t d 2 , … , t_{d1},t_{d2},…, td1td2正常运行时间分别为 t u 1 , t u 2 , … , t_{u1},t_{u2},…, tu1tu2则系统的稳态可用性为:
        • 在这里插入图片描述
        • 其中:
        • 在这里插入图片描述
        • (7.1)式可以变成
        • 在这里插入图片描述
  • 估算平均无故障时间的方法
    • (1)符号
      • E T E_T ET:测试之前程序中错误总数;
      • I T I_T IT:程序长度(机器指令总数);
      • τ τ τ:测试(包括调试)时间;
      • E d ( τ ) E_d(τ) Ed(τ):在0至 τ τ τ期间发现的错误数;
      • E c ( τ ) E_c(τ) Ec(τ):在0至 τ τ τ期间改正的错误数。
  • (2)基本假定
    • ① 单位长度里的错误数 E T E_T ET/ I T I_T IT近似为常数。通常 0.5 × 1 0 − 2 0.5×10^{-2} 0.5×102 E T E_T ET/ I T I_T IT 2 × 1 0 − 2 2×10^{-2} 2×102
    • ② 失效率正比于软件中潜藏的错误数,平均无故障时间MTTF与剩余的错误数成反比。
    • ③ 假设发现的每一个错误都立即正确地改正了,即 E c ( τ ) = E d ( τ ) E_c(τ)=E_d(τ) Ec(τ)=Ed(τ)
      • a.剩余的错误数
        • 在这里插入图片描述
      • b.单位长度程序中剩余的错误数
        • 在这里插入图片描述
  • (3)估算平均无故障时间
    • ① 平均无故障时间与单位长度程序中剩余的错误数成反比(K经典值为200),即
      • 在这里插入图片描述
    • ② 估算平均无故障时间的公式,可以评价软件测试进展情况。由(7.5)式可得:
      • 在这里插入图片描述
  • (4)估计错误总数的方法
    • ① 植入错误法
      • 假设人为地植入的错误数为Ns,经过一段时间的测试之后发现ns个植入的错误,还发现了n个原有的错误。则估计出程序中原有错误的总数为:
      • 在这里插入图片描述
      • 其中估计出程序中原有错误的总数即是错误总数 E T E_T ET的估计值。
    • ② 分别测试法
      • 假定测试员甲乙发现有标记错误和发现无标记错误的概率相同,则可以估计出测试前程序中的错误总数为:
      • 在这里插入图片描述
      • 其中,测试员甲发现的错误数为 B 1 B_1 B1,测试员乙发现的错误数为 B 2 B_2 B2,两个测试员发现的相同错误数为 b c b_c bc
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐