【读书笔记】之软件测试

来源:互联网 发布:淘宝上能买身份证嘛 编辑:程序博客网 时间:2024/05/29 18:59

0.参考教材

《软件工程原理及应用》 陈世鸿,朱福喜,黄水松,陈磊主编;武汉大学出版社

1.引论

1.1 什么是软件测试

软件测试主要是对制作的软件产品进行检查和测试,及时地发现程序中的故障和逻辑错误,以保障软件产品的可靠性。软件测试是保证软件质量的关键步骤,也是提高软件可靠性的重要手段,因此它是软件工程的的重要重要组成部分之一。

软件测试的内容包括两个方面,即文档和程序。

软件测试的宗旨是要采用费用最少而效果最好的方法提高软件产品的质量。

Dijkstra关于软件测试有一句极精辟的话“测试只能证明程序有错,不能保证程序无错”。

 

1.2 软件测试的目标

G.Myers在他的优秀著作《软件测试技巧》中,精辟的阐述测试的目的或定义:

  1. 程序测试是为了发现错误而执行程序的过程;
  2. 好的测试方案是极可能发现迄今为止尚未发现的错误;
  3. 成功的测试是能够发现以前尚未发现的错误。

由此可见,传统观念“程序测试是为了证明程序中不存在错误”,“成功的测试是一个未能发现错误的测试”是不正确的。

1.3 软件测试的原则

  1. 预先确定测试结果
  2. 软件的开发者(或部门)不应该测试自己的程序
  3. 制定严格的测试计划,防止测试的随意性
  4. 设计和选择测试方案要有利于发现错误
  5. 集中力量测试容易出错的程序段
    • 在许多程序中,错误好像是成群出现的,这些错误往往比较集中在一段程序中。存在错误的概率与这段程序中发现的错误成比列。这就是所谓群集现象
  6. 保存好测试计划,测试方案,错误数据统计和分类,以及最终的分析报告。

2.软件测试方法

软件测试通常有三种方法,第一种是程序正确性证明,即验证;第二种是静态测试,即不执行被测试的程序而发先程序中的错误;第三种是动态测试。

2.1 程序正确性证明

程序正确性证明是从理论上对程序的正确性进行论证,通过证明可以得出程序逻辑上是否正确。

在许多情况下,一个完全的形式证明可能是不必要的。在某些情况下,若不能实现完全测试,则也不可能实现完全的形式证明。然而,我们常常用程序正确性证明所开发的推理风格来指导测试过程,以增强对程序的信任,有时可以把某些性质的程序证明和其他性质的测试结合起来。

2.2 静态测试

所谓静态测试是指不执行程序而找出程序存在错误的方法。这种方法以人工的,非形式化的方法对程序进行分析和测试,它是不依赖于计算机的测试。实践表明,静态测试可以发现大约30%-70%的逻辑设计错误和编码错误。

2.2.1 功能检查(自我测试)

功能检查也叫自我测试,由程序员将模块功能(说明,算法,语法规则),流程图和编码对照起来反复阅读,检查程序的语法和逻辑错误。

2.2.2 群体检查

群体检查是由自于人听社记者对功能说明,流程图,程序编码的自我测试等情况的汇报之后,对程序进行动态分析的过程。

2.2.3 人工运行检查

人工运行检查是由人扮演计算机来执行程序,将测试方案按程序的逻辑结构执行一遍,从而找出程序的错误供测试者分析。

2.3 动态测试

静态测试主要是检查程序的逻辑设计和编码错误,但在理论上和实践上还存在局限性,所以还比寻进行动态测试。

所谓动态测试,就是把程序看作函数,取函数定义域中的每一个元素作为输入,实际运行程序,检查程序的执行结果是否全部落在函数的值域之内,以此来检查程序的正确性,可靠性和有效性。

  1. 如果产品要实现的功能是已知的,就可以分别测试是否达到每个功能要求,称之为“黑盒测试”
  2. 如果知道产品的内部逻辑结构和处理过程,可以根据规格说明来完成内部操作的测试,称之为“白盒测试”

2.3.1 黑盒测试法(功能测试法)

黑盒测试法又称为功能测试法,它是在软件接口上进行测试,根据对软件功能的分析,推演出函数定义域中有代表性的元素组成测试方案。测试者使用这种方法时,把程序看成一个黑盒,完全不考虑程序内部的结构和处理过程。其目的是用来证明与程序内部工作无关的功能需求的有效性,很少考虑软件的内部逻辑结构。

2.3.2 黑盒测试方案的设计

2.3.2.1 划分等价类

  1. 划分等价类的规则
    • 值的范围
    • 值的个数
    • 值约束
    • 值的规则(如文件名以字母开头)
    • 等价类的进一步划分
  2. 测试方案

划分等价类后,应根据等价类设计测试方案,主要步骤如下:

  1.  
    1. 为每个等价类规定一个唯一的编号。
    2. 包含合理的等价类。设计一个新的测试方案时,应选取尽可能多的测试方案覆盖尚未被包含的合理等价类。
    3. 包含一个不合理的等价类。设计一个新的测试方案,使它仅包含一个尚未被包含的不合理的等价类。否则,多个不合理的等价类交叉在一起会影响测试效果。

2.3.2.2 边界值分析

程序中大量的错误常常会出现在输入域的边界位置,而非“中间”。这里所说的边界值是指相对于输入等价类和输出等价类而言的。

使用边界值分析法设计测试方案时,首先应去顶边界条件,选取刚好等于,稍小于和稍大于等价类边界的数据作为测试数据。以下几点可供参考:

  1. 如果输入条件规定了取值的范围,首先选取这个范围的边界测试条件,然后编写一些刚好超过此范围的测试条件的例子。
  2. 如果输入条件规定了输入数据的个数,则应分别为最小个数,最大个数,比最小个数少一,比最大个数多一设计测试方案。
  3. 除考虑输入等价类之外,还应考虑输出等价类来选取测试方案。
  4. 如果程序的输入和输出是个有序集(如线性表),则应把注意力集中在集合的第一个和最后一个元素上。

用边界值分析法设计的测试方案更全面,更具有代表性,发现错误的概率更高。但找出边界条件时很困难,需要实践经验和创造性劳动。

边界值分析法和等价类划分法的主要区别如下:

  1. 边界值分析法不是从某个等价类中任意选取一个作为代表,而是选取一个或几个元素,等价类中每个边界值都是测试对象。
  2. 边界值分析法不仅要考虑输入条件,还要把输出等价类作为测试方案。

2.3.2.3 错误推测法

所谓错误推测法,就是通过人们的经验或直觉,推测程序中可能存在的某些错误类型和容易发生的特殊情况,并依此选择测试方案检查这些错误。错误推测法主要是凭借测试者在实践中积累的经验,所以没有确定的测试步骤。

2.3.3 白盒测试法(逻辑覆盖法,结构测试法)

白盒测试法又称逻辑覆盖法或结构测试法,它是根据对软件内部逻辑结构的分析到处测试方案,用来对软件的过程性细节细致检查。测试者把程序看作一个透明的盒子,利用过程设计的控制结构检查内部的逻辑结构和处理过程。使用白盒测试,测试方案对程序逻辑覆盖的成都决定测试完全性的程度。

2.3.4 白盒测试方案的设计

使用白盒测试到处的测试方案可以做到:

  1. 确保模块的所有独立路径至少测试一次
  2. 所有逻辑判断的真假两种情况都被测试
  3. 在循环的边界和运行界限内执行所有的循环
  4. 测试内部数据结构以确保它们的有效性

下面例举一些常用的白盒测试方案:

  1. 语句覆盖:选择足够的测试数据,使程序中的每个可执行的语句至少执行一次。
  2. 判定覆盖(分支覆盖):一种较强的逻辑覆盖,测试时设计出足够多的测试数据,使得程序中的每一个判断的取真分支和取假分支至少执行一次。
  3. 条件覆盖:使用足够多的测试数据,使得判定中的每个条件的所有可能的结果至少出现一次。
  4. 判定—条件覆盖:既满足判定覆盖的标准又满足条件覆盖的标准。
  5. 条件组合覆盖:选取足够多的测试数据,使得每个判定表达式中的条件的各种可能的组合至少执行一次。

说明:

  1. 在一个判定表达式中常常包含多个条件
  2. 条件覆盖不一定包含判定覆盖,判定覆盖也不一定包含条件覆盖。
  3. 满足条件组合覆盖的测试数据一定能满足判定覆盖,条件覆盖和判定—条件覆盖。

3.软件测试的步骤和策略

  1. 单元测试
  2. 联合测试
  3. 有效性测试
  4. 系统测试
  5. 验收测试

3.1 单元测试

单元测试是指被测试程序是单个子程序,过程的逻辑测试。单元测试的主要任务是验证其功能和接口说明是否有不符合的情况,以及编码错误。

单元测试集中在每个单独的程序块中,消除快内的逻辑,功能上的缺陷和错误,保证每个块作为一个单元能正确执行并为上一级测试作准备。

经过静态测试之后,应该集中注意力逐一测试程序中的每一个单元,而不是把程序作为一个整体来测试,理由如下:

  1. 易于排错。
  2. 利于联合测试。
  3. 利用单元测试确认详细说明书。
  4. 可并行测试。

在单元测试中主要使用白盒测试法,尽可能达到彻底测试;黑盒法辅助功能测试,要达到对任何合理和不合理的输入都能够鉴别和响应。

3.1.1 单元测试的内容

  1. 单元接口。在进行单元测试前,首先应对单元接口的数据流进行测试,因为接口测试是其它测试的基础,如果数据流不能正确的进入和退出,其它的测试就无法进行。
  2. 局部数据结构的测试。对局部数据结构应进行仔细测试,因为局部数据结构常常事错误的策源地。
  3. 重要路径测试。由于测试具有不可穷尽性,因此选择适当的测试方案对单元中重要执行路径充分测试是十分必要的。其目的是为了发现计算错误,比较错误或控制流错误。
  4. 错误处理。错误处理应该是程序功能的一部分,一旦出现粗无时应执行相应的出错处理路径,或终止程序运行。
  5. 边界测试。边界测试是单元测试中最后的也可能是最重要的工作。

3.1.2 单元测试的过程

单元一般不是一个独立完整的程序,在进行单元测试之前,还必须为每个单元测试编写驱动程序支撑程序

在通常的应用中,驱动程序与“主程序”并无区别,它接收测试数据,将这些数据传送给被测试的单元,并打印有关的结果。

支撑程序则代替被测试的单元所调用的单元,有时也将支撑程序成为“虚子程序”,它提供由它代替的单元接口,数据处理尽可能少,打印并检查入口信息,将控制返回给调用它的单元。

驱动程序和支撑程序都是要另外编写的,需要花费不少的精力和时间。因为应尽量设计的简单些,意减少软件开发的开销。然后许多单元却不能用“简单的”低开销来充当单元测试。在这种情况下,测试工作就要推迟到联合测试时进行,当然,这时仍需要编写少量的驱动程序和支撑程序。

3.2 联合测试

在单元测试的基础上,要把每个单元按照设计要求逐步联接起来进行联合测试,主要目的是发现与接口有关的错误。

单元的联合集成测试有两种方式,非增式测试和增式测试

非增式测试就是先分别测试每个单元,再把所有单元按设计要求联接成完整的程序系统。

增式测试是把一个要测试的单元同已经测试好的单元联接起来进行测试,测试完毕后,再把下一个应该测试的单元联接起来进行测试,每次只增加一个单元。这种方法实际上同时完车单元测试和联合测试。

 

这两种方法的主要优缺点如下:

  1. 增式测试工作量小。非增式测试需要对每个单元编写驱动程序和支撑程序,工作量较大。而增式测试可利用已测试过的单元作为部分驱动和支撑程序,其工作量小。
  2. 增式测试发现错误早。增式测试可以较早的发现单元接口错误,而非增式测试只有等到各单元联接在一起后才能发现单元之间的接口错误。
  3. 增式测试的彻底性。增式测试把已经测试好的单元与心胆原联结起来进行测试,在新环境下,又要对已经测试好的单元进行测试,随着单元数的不断增加,有些单元要经受多次测试,显然这种方式对程序的测试更彻底。
  4. 增式测试需要较多的机器时间。
  5. 非增式测试可并行进行测试。

总的来说,增式测试是更适合的测试方案

 

对增式测试其单元的增加有自顶向下和自底向上两种单元联接方法。

3.2.1 自顶向下

自顶向下测试是一种增式集成软件结构的方法,从主单元(主程序)开始,沿着软件的控制层次向下移动,从而逐渐把各个单元联结起来,已经测试过的单元和新单元的联接有两种策略,即深度优先和广度优先。

3.2.1.1 决定测试顺序的基本原则

  1. 尽早测试关键单元。
  2. 尽早测试包含输入输出操作的单元。因为测试了具有这些功能的单元后,有利于测试数据的输入和测试结果的输出。

3.2.1.2 测试步骤

  1. 把主控单元作为测试驱动程序,其直接下属单元用支撑程序代替。
  2. 根据选择的联接策略(深度优先或广度优先),用实际的单元逐个代替下属的支撑单元。
  3. 每联接一个单元就测试一个单元
  4. 可以进行回归测试,即部分地或全部地重复测试曾经测试过的单元,保证不断发现新的错误
  5. 重复1-4,直至完成整个软件系统为止。

3.2.1.3 优点

  1. 能够较早发现并纠正主要界面的错误。
  2. 不需要编写驱动程序。
  3. 用户能够在早起看到系统的主要功能。
  4. 测试所占的机器时间在软件开发的整个期间能够保持一定的稳定性。

3.2.1.4 缺点

  1. 要求编写支撑程序,且支持程序复杂,测试方案设计困难;
  2. 建立测试条件和判定测试结果困难;
  3. 容易遗忘必要的测试;
  4. 并行测试困难。

3.2.2 自底向上

自底向上和自顶向下的测试正好相反,它是根据自底向上开发技术而来的,一般在程序设计完成后才能开始测试,从软件结构最底层的单元开始联接和测试。

3.2.2.1 测试步骤

自底向上测试通常是在系统开发的后期进行,即在系统分析,系统设计,程序设计完成之后开始进行测试,此时系统的所有单元均已存在。实现步骤如下:

  1. 将底层单元组合成实现某个特定的软件子功能;
  2. 编写一个驱动程序(测试控制程序)来协调测试的输入和输出;
  3. 测试单元集
  4. 沿着软件结构向上去掉驱动程序,将新单元联接起来。

3.2.2.2 优点

  1. 不需要编写支撑程序;
  2. 可尽早进行并行测试;
  3. 可尽早发现关键单元的错误;
  4. 容易建立测试条件;
  5. 容易判断测试结果。

3.2.2.3 缺点

  1. 要编写驱动程序;
  2. 要求先集成为子系统;
  3. 接口出错发现迟;
  4. 系统轮廓形成晚。

3.3 有效性测试

软件的功能和性能能够满足用户合理的要求,则软件是有效的。

软件的有效性测试一般使用黑盒测试法。

有效性测试需要验证软件是否与用户要求一致的测试方案。此外还必须验证文档资料是否完整准确,软件的可移植性,兼容性和可维护性。

有效性测试过程的一个重要内容是对软件的配置进行复查,其目的是保证所有的软件配置的所有成分(如用户文件,设计文件代码表,测试文件等)齐全,其质量符合要求,支持维护阶段所必须的细节,而且还要编排好目录。

3.4 系统测试

系统测试是通过有效性测试的软件作为整个计算机系统的一部分,与硬件,外设等其它系统结合起来,对计算机系统进行一系列的联合测试和有效性测试。

系统测试的目的是,将软件与系统需求定义进行比较,发现软件与定义不符合或相矛盾的地方。

系统测试的种类有:

  1. 功能测试。逐步对照规格说明,检查程序是否满足了“做什么”。
  2. 容量测试。其目的是通过让程序处理大量的数据,考虑这些程序是否能处理规定数量的任务。
  3. 强度测试。强度测试是指程序能否在单位时间内完成规定的最大工作容量(数),让程序咋高负荷情况下工作。
  4. 便利性测试。对接口结构,输出结果是否无法理解,出错信息是否简明易懂,操作是否方便等。
  5. 安全性测试。精心设计一些测试方案检查程序的安全性。
  6. 存储容量测试。测试的内容有内存和外存的容量,临时文件或文件溢出及大小等。
  7. 配置测试。主要是对程序所需的资源进行测试,例如测试输入/输出设备,操作系统,语言等的要求。
  8. 兼容/转换性能测试。特别对那些新版本的程序的测试,既要测试新的版本与旧版本的兼容性,又要考虑将来版本更新后的扩充问题。
  9. 可安装性测试。对安装步骤的考核测试,特别一些系统软件,对其安装过程进行测试是十分重要的。
  10. 可靠性测试。所谓软件的可靠性,是指给定的时间内 ,特定的环境下软件正确运行的概率
  11. 恢复测试。当硬件故障,引起程序和数据出现错误之后,测试整个系统能否恢复正常工作。
  12. 维护性测试。对系统提供的可供维护的手段进行测试,例如对诊断程序,存储器中的转储程序,维护规程等进行测试。
  13. 文档资料测试。检查提供给用户的文档资料是否齐全和准确。
  14. 规程测试。测试各类人员(如系统操作人员,数据库管理人员等)应遵循的规程是否合理可行。

3.5 验收测试

验收测试是在用户参与的情况下进行的,主要使用实际数据进行测试,其目的是验证系统确实能够满足用户的需要,测试的内容与联合测试基本相同,测试中发现的错误往往是系统要求说明书中的错误。

 

 

2010.9.21 (中秋前夜,写了4个多小时,好累呀:)

-END-


4 相关名词解释

  1. 回归测试是在软件维护阶段,对软件修改之后进行的测试.其目的是检验对软件进行的修改是否正确.
  2. 所谓软件的可靠性,是指给定的时间内 ,特定的环境下软件正确运行的概率 .
  3. 简述软件生命周期模型中的瀑布模型.
    问题定义——>可行性分析——>需求分析——>概要设计——>详细设计——>编码——>测试——>维护
  4. 负载测试通常是指模拟多个用户同时使用系统的服务来模仿一个软件程序期望用途的做法.
原创粉丝点击