【SEU&SE】软件测试及应用课程笔记

【SEU&SE】软件测试及应用课程笔记

  • README
  • 0. 课程前言
    • 0.1. 软件测试的地位
    • 0.2. 软件测试的方法
    • 0.3. 课程考评
  • 1. UNIT-1 软件测试概述
    • 1.1. 软件测试的产生背景(了解)
      • 1.1.1. 软件危机
      • 1.1.2. 几个软件的概念
      • 1.1.3. 为什么会出现软件缺陷
      • 1.1.4. 软件测试的意义
    • 1.2. 软件测试的发展(了解)
    • 1.3. 软件测试基本概念
      • 1.3.1. 软件测试的定义(IEEE Std 610.12 - 1990)
      • 1.3.2. 软件测试的目的
      • 1.3.3. 软件测试的原理/原则/准则
      • 1.3.4. 软件测试过程模型
      • 1.3.5. 软件测试的过程
      • 1.3.6. 软件测试环境
    • 1.4. 软件测试现状和趋势
    • 1.5. 软件测试工具
  • UNIT-2 白盒测试
    • 2.1. 基本概念
      • 2.1.1. 定义
      • 2.1.2. 实施者
      • 2.1.3. 步骤
      • 2.1.4. 进入和退出条件
    • 2.2. 静态白盒测试
      • 2.2.1. 基本概念(定义及优特点)
      • 2.2.2. 桌面检查(Desk Checking)
      • 2.2.3. 同行评审(Peer Review)
      • 2.2.4. 代码走查(Walkthrough)
      • 2.2.5. 代码审查(Inspection)
    • 2.3. 动态白盒测试
      • 2.3.1. 基本概念
      • 2.3.2. 覆盖准则
      • 2.3.3. 语句覆盖
      • 2.3.4. 判定覆盖(分支覆盖)
      • 2.3.5. 条件覆盖
      • 2.3.6. 判定条件覆盖
      • 2.3.7. 条件组合覆盖
      • 2.3.8. 路径覆盖(Path Coverage)
      • 2.3.9. 基本路径测试方法
      • 2.3.10. 基于控制流的测试——循环的处理
      • 2.3.11. 基于数据流的测试
  • UNIT-3 黑盒测试
    • 3.1. 基本概念
    • 3.2. 黑盒测试面临的挑战
    • 3.3. 随机进行黑盒测试
    • 3.4. 黑盒测试方法基础
      • 3.4.1. 基于需求的测试
      • 3.4.2. 正面和负面测试用例
    • 3.5. 黑盒测试方法
      • 3.5.1. 等价类划分法
      • 3.5.2. 边界值分析法
      • 3.5.3. 关于等价划分和边界值分析
      • 3.5.4. 因果分析法
      • 3.5.5. 决策表方法
      • 3.5.6. 因果图和决策表
      • 3.5.7. 因果图和决策表
      • 3.5.8. 正交数组测试
      • 3.5.9. 蜕变测试
    • 3.6. 黑盒测试总结
    • 3.7. 灰盒测试
    • 3.8. 黑盒测试工具
      • 3.8.1. 功能测试工具
  • UNIT-4 单元测试与集成测试
    • 4.1. 单元测试
      • 4.1.1. 软件单元
      • 4.1.2. 基本概念
      • 4.1.3. 单元测试考虑事项
      • 4.1.4. 单元测试规程
    • 4.2. 集成测试
      • 4.2.1. 基本概念
      • 4.2.2. 集成测试策略(如何进行集成测试)
      • 4.2.3. 集成测试方法选择指南
      • 4.2.4. 集成测试总结
    • 4.3. 测试插桩(Instrumentation)
      • 4.3.1. 背景
      • 4.3.2. 原理
      • 4.3.3. 两类插桩技术
      • 4.3.4. 插桩方式
      • 4.3.5. 白盒测试插桩技术
      • 4.3.6. 黑盒测试插桩技术
    • 4.4. 单元/集成测试工具(略)
  • UNIT-5 J-Unit(略)
  • UNIT-6 系统测试、确认测试、回归测试
    • 6.1. 系统测试
      • 6.1.1. 基本概念
      • 6.1.2. 系统测试VS组件和集成测试
      • 6.1.3. 功能系统测试
      • 6.1.4. 非功能系统测试
    • 6.2. 确认测试
    • 6.3. 回归测试
      • 6.3.1. 背景
      • 6.3.2. 概念

README

本篇笔记内容主要摘抄自东南大学软件学院廖力老师于2019年开设的《软件测试及应用》的课程PPT,小部分内容摘抄自互联网,故本篇笔记仅供学习参考使用,严禁商用
其中被标记部分为课程重点。


0. 课程前言

0.1. 软件测试的地位

  • 软件测试应占总工作量的40%~55%,测试费用达30%,测试人员与开发人员的比例应达到1~2:1。但是目前软件测试人员急缺,比较好的公司中测试人员与开发人员的比例也只能达到1:2~1。

0.2. 软件测试的方法

  • 白盒测试:知道完整代码;
  • 黑盒测试:不知道代码
  • 灰盒测试:只知道API接口;
  • 回归测试:相当于补考;

0.3. 课程考评

  • 课程考评:平时成绩10%+上机实验20%+期末考试成绩70%;
  • 试卷结构:选择题 1 * 10道,填空题 1 * 20道,简答题 5 * 4道,设计题4-5道;

1. UNIT-1 软件测试概述

1.1. 软件测试的产生背景(了解)

1.1.1. 软件危机

  • 20世纪60年代出现了所谓的“软件危机”概念;
  • 危机表现:维护费用上升,可靠性差,进度无法预测……;
  • 危机原因:缺乏规范化工程约束导致缺陷的不断累积与放大效应
  • 软件危机的解决:软件工程,即将工程化思想应用于软件开发;

1.1.2. 几个软件的概念

  • 软件质量:1. 用户需求;2. 开发规范;3. 隐含要求;
  • 软件可靠性:给定时间内无故障运行的概率;
  • 软件错误:不满足用户预期;

1.1.3. 为什么会出现软件缺陷

  • 产品说明书(主要原因):随意、易变、沟通不足
  • 设计(次要原因):随意、易变、沟通不足;
  • 编码:软件复杂度、进度压力、低级错误;
  • 其他:理解错误;

1.1.4. 软件测试的意义

  • 是保证软件质量的重要手段,软件测试深入软件开发的每个阶段,在有限的开发条件下,尽最大限度地保证软件质量;

1.2. 软件测试的发展(了解)

  • 1970s:Myers:测试是为了证明程序有错,而不是证明程序无错,目的是为了提高产品质量;一个好的测试用例是能够发现至今还未发现的错误;一个成功的测试是发现了至今未发现的错误的测试
  • 1980s:测试基础理论和实用技术开始形成;软件测试的目的不仅仅是为了发现软件缺陷和错误,同时也对软件进行度量和评估,作为软件质量保证的重要手段;1983年,IEEE给出软件测试的定义;
  • 1990s~至今:测试理论和技术进一步完善;商业化软件测试和开源软件测试工具;

1.3. 软件测试基本概念

1.3.1. 软件测试的定义(IEEE Std 610.12 - 1990)

  • (1)在特定的条件下运行系统或构件,观察或记录结果,对系统的某方面作出评价
  • (2)分析某个软件项以发现现存和要求的条件之差别并评价此软件项的特性

1.3.2. 软件测试的目的

  • 确保软件质量
  • 确保软件开发过程方向的正确性

1.3.3. 软件测试的原理/原则/准则

  • 原理1:用户需求至上(不能盲目追求大而全,测试的目标是在用户发现缺陷前找到它们)
  • 原理2:测试是有计划的活动(测试贯穿于全部软件生存周期)(软件测试的第一步是制定测试计划,而不是创建测试用例)
  • 原理3:缺陷的出现具有集群性(80%的错误可能起源于20%的模块,因为某个人写的代码可能bug就特别多)
  • 原理4:测试应从“小规模”走向“大规模”(最初测试单个程序模块,然后在集成的模块簇中找缺陷,最后在整个系统中找缺陷)
  • 原理5:穷尽测试(完全测试)是不可能的
  • 原理6:有效的测试应由第三方独立进行(有些测试应避免由开发人员进行)
  • 原理7:测试无法揭示所有缺陷(测试可以报告说缺陷存在,但没有找到缺陷的话不能说明软件没有缺陷)
  • 原理8:测试的杀虫剂悖论(潜在缺陷对已进行的测试具有免疫力)
  • 原理9:测试是有风险的行为(测试不足的话会造成遗漏缺陷,测试过度的话会导致昂贵的测试费用,所以需要一个最优测试量)
  • 原理10:并非所有的软件缺陷都需要修复(要考虑修复的代价,比如时间、风险、性价比等等)

1.3.4. 软件测试过程模型

  • 概念:软件测试的工作框架;
  • V模型:应用于瀑布式开发;单元测试 -> 集成测试 -> 系统测试 -> 验收测试;
    【SEU&SE】软件测试及应用课程笔记_第1张图片
  • W模型:根据W模型突出了测试驱动开发的方法V&V:确认和验证
    【SEU&SE】软件测试及应用课程笔记_第2张图片
  • 前置测试模型:实质是W模型的细化,把测试和开发融合到一个过程;
  • H模型:软件过程分为两条线,一条是开发线、一条是测试线,当测试准备完成时,开发线暂停,进入测试就绪点,测试执行后开发现继续进行,直到遇到下一个测试就绪点;这是目前应用最广泛的;

1.3.5. 软件测试的过程

  • Step1:拟定软件测试计划;
  • Step2:编制软件测试大纲;
  • Step3:设计和生成测试用例:
    测试用例定义1:一组输入即运行前提条件,和为某特定的目标而生成的预期结果
    测试用例定义2:一个文档,详细说明输入、期望输出,和为一测试项所准备一组的执行条件
    PS:定义1时测试用例的实质,定义2时测试用例的一种存在方式;
    测试用例三要素:输入、执行条件、期望输出
    – 测试用例设计准则:
    代表性:代表合理和不合理、合法和非法、边界和越界以及极限数据、各种操作环境等;
    可判定性:测试执行结果的正确性是可判定的或可评估的;
    可再现性:对同样的测试用例,系统执行结果应当相同;
  • Step4:实施测试;
    在每个测试周期,测试工程师依据测试大纲和测试用例,通过执行被测试软件,或检查程序代码和文档,对其进行测试;
  • Step5:分析测试结果;

1.3.6. 软件测试环境

– 测试环境 = 软件 + 硬件 + 网络;
– 测试环境要点:真实、干净、无毒、独立;

1.4. 软件测试现状和趋势

– 国际现状:知名IT企业中,开发人员和测试人员比例通常为1:1,微软甚至达到1:2;
– 国内现状:软件测试逐渐受到重视;存在不用程度的测试人才缺口;高素质的测试人才紧缺;

1.5. 软件测试工具

  • 白盒测试工具:JUnit、TestNG、C++Test;
  • 功能测试工具:Selenium、QTP;
  • 性能测试工具:LoadRunner、Jmeter(针对Java,开源);
  • 测试管理工具和测试辅助工具:禅道(国产的开源的项目管理软件)、Jira;
  • 测试工具在软件测试中的作用:
    – 速度:自动化测试远高于手工执行测试;
    – 效率和成本:推进软件开发进度、降低开发和维护成本;
    – 准确度和精度:工具能快速且无差错地执行测试用例或测试脚本;

UNIT-2 白盒测试

2.1. 基本概念

2.1.1. 定义

  • 一种基于源程序或代码的测试方法。依据源程序或代码结构与逻辑,生成测试用例以尽可能多地发现并修改源程序错误;分为静态和动态两种类型;

2.1.2. 实施者

  • 单元测试阶段一般是由开发人员进行,集成测试阶段由测试人员和开发人员共同完成

2.1.3. 步骤

  • 动态:程序图、生成测试用例、执行测试、分析覆盖标准、判定测试结果;
  • 静态:桌面检查、代码走查、代码审查(需要较长时间,甚至需要第三方,审查会成为若干个milestone);

2.1.4. 进入和退出条件

  • 进入条件:编码开始时;
  • 退出条件:满足了一定的覆盖率……;

2.2. 静态白盒测试

2.2.1. 基本概念(定义及优特点)

  • 定义:不执行软件的条件下有条理地仔细地审查软件设计、体系机构和代码,从而找出软件缺陷的过程,有时称为结构化分析;
  • 理由:尽早发现软件缺陷、为后续测试中涉及测试用例提供思路;比起动态测试,静态测试耗时少、检查出错误的概率大;
  • 特点:不用在计算机上执行程序,而是由人阅读代码;
  • 测试目标:代码是否满足功能需求、代码是否与设计一致、代码是否遗漏某些功能、代码是否适当地处理错误;
  • 优点:
    – 可发现某些机器发现不了的错误;
    – 利用不同人对代码的不同观点;
    – 对照设计,确保程序能完成预期功能;
    – 不但能检测出错误,还可以尝试确定错误根源;
    – 节约计算机资源,但以增加人工成本为代价;
    – 尽早发现缺陷,避免后期缺陷修复造成的巨大压力;
  • 方法(形式化程度由低到高、耗费的成本由低到高):桌面检查、同行评审、代码走查代码审查

2.2.2. 桌面检查(Desk Checking)

  • 开发人员自己做
  • 桌面检查记录格式:行号、变量、条件、输入输出;
  • 优点:编码者容易理解和阅读自己的代码、开销小、尽早发现缺陷;
  • 缺点:开发人员不是实施测试的最佳人选、依靠个人勤奋和技能(说白了靠自觉,没有约束力,有效性难以保证);

2.2.3. 同行评审(Peer Review)

  • 召集小组成员进行初次审查;

2.2.4. 代码走查(Walkthrough)

  • 一个同行不够,来多个同行;
  • 比Peer Review更为正规化,以组为单位进行代码审查,但也是往往不是有计划的,是在前两个方法失效的情况下进行的;
  • 规程:作者逐行通读代码,评审者随时可以提问;

2.2.5. 代码审查(Inspection)

  • 除了开发人员还需要管理人员来盖章之类的;
  • 代码审查小组:主持人(多面手)、表述者(会上通读程序,但不是作者,即由别人来读,必要时再呼叫作者)、作者(负责必要时的解释)、评论员(找出缺陷)、记录员;
  • 步骤:计划(Plan)、概述(Overview Meeting)、准备(Preparation)、审查会议(Inspection Meeting)、审查报告(Report)、返工(Rework)、跟进(Follow up);

2.3. 动态白盒测试

2.3.1. 基本概念

  • 特点:不但要提供软件源代码,还要提供可执行程序,测试过程需要在计算机上执行程序
  • 试图检查:
    – 对程序模块中的所有独立执行路径至少执行一次;
    – 对所有逻辑判断的取值都至少执行一次;
    – ……

2.3.2. 覆盖准则

  • 包括控制流覆盖和数据流覆盖
  • 意义:对“测试执行到何时才是足够的”的定量回答;
    作用:测试软件的一种度量;
  • 逻辑覆盖:白盒测试要求对被测试程序结构特性做到一定程度的覆盖;
  • 基于控制流方法:语句覆盖、判定覆盖、条件覆盖、判定条件覆盖、条件组合覆盖、路径覆盖(覆盖程序中所有可能的执行路径)、基本路径测试方法
    【SEU&SE】软件测试及应用课程笔记_第3张图片
  • 基于数据流的测试

2.3.3. 语句覆盖

  • 在程序流程图中每一个块都被执行过一次,即保证程序中的每条语句都执行一遍;100%的语句覆盖可能很困难,例如处理错误的代码片段、小概率事件、不可达代码;100%的语句覆盖也是很脆弱的,无法发现某些严重的问题,比如语句覆盖无法覆盖所有条件;

2.3.4. 判定覆盖(分支覆盖)

  • 保证每个判定取True和False至少一次;执行完判定覆盖后就不需要再执行语句覆盖了,因为肯定会执行所有语句;判定覆盖忽略了表达式内的条件,不能发现每个条件的错误,例如 if(condition1 && (condition1 || function1())) 中的依赖条件 function1() 不会被执行;优点:简单,包含语句覆盖并避免了语句覆盖的问题;

2.3.5. 条件覆盖

  • 保证每个判断中的每个条件的取值至少满足一次;条件覆盖不能保证程序的所有分支都被执行;条件覆盖不要求判定结果的不同逻辑值,因此可能比语句覆盖或判定覆盖要弱;【PS:&&是短路符,即如果判定的值已知的话余下的条件就不执行了,然而AND会执行所有判定条件】;

2.3.6. 判定条件覆盖

  • 保证每个条件和条件组成的判断的取值,即判定覆盖和条件覆盖的集合;被测试程序的每个判定的所有可能结果都至少执行一次,并且,每个判定中的每个条件的所有可能结果至少出现一次;错误屏蔽:指原子条件取值改变不会影响判定结果,因此该条件上的取值错误是不可见的;【判定覆盖、条件覆盖、判定条件覆盖均要避免全True或者全False的情况】;

2.3.7. 条件组合覆盖

  • 保证每个条件的取值组合至少出现一次;代价昂贵:2^n组合数目,n为原子条件数某些条件组合是不可能存在的;条件组合覆盖不要求避免全True或者全False的情况;综合前五个覆盖来看,条件组合覆盖的强度是最强的;但该方法依然有缺陷,例如代价昂贵、部分路径不会经过;考虑短路的条件组合覆盖的测试用例数会大幅度减少,所以可以利用短路效应寻找最小测试用例集,即测试用例的约简;

2.3.8. 路径覆盖(Path Coverage)

  • 选择足够的测试用例,保证每条可能执行的路径都至少经过一次(如果程序中包含环路,则要求每条环路至少经过一次);优点:相对彻底的测试;缺点:路径分支可能以指数级增加、不可达路径存在、并未测试各分支中的条件;路径覆盖是比较强的覆盖标准,但是不能代替条件覆盖和条件组合覆盖;路径覆盖实际上考虑了程序中各种判定结果的所有可能组合,但它未必能覆盖判定条件结果的各种可能情况;

2.3.9. 基本路径测试方法

  • 寻找基本路径,根据基本路径构造测试用例,保证每条路径至少执行一次;
  • 测试用例设计过程:过程图转化为流图,根据环复杂度找出基本路径,设计测试用例;实际上,这就是将程序流程抽象为连通图,通过对图的问题求解得到程序的基本路径;
  • 流图:用来描述程序中的逻辑控制流;由结点(表示一个或多个过程语句,即一个语句或者一个判定条件)、边(表示控制流)、域(由边和结点限定的区间):
    – 流图的基本结构:Sequence、If、While、Until、Case;
    – If语句里面的所有条件,每个条件是一个独立的标号,即进行一次人为的短路,所以注意AND和OR的方式是不一样的;
    – 流图会把所有逻辑判定条件分隔开,即每个条件有一个自己的编号;
    – 入口:入度为0;出口:出度为0;
  • 基本路径(独立程序路径):任何贯穿程序的、至少引入一组新的处理语句或一个新的判断(条件)的程序通道
  • 基本路径的度量——环复杂度:环复杂度度量基本路径数,是所有语句被执行一次所需测试用例数的上限,环复杂度=基本路径数
    – 环复杂度的计算:
    方法1:等于域的数量
    方法2:V(G) = E -N + 2,E为边,N为结点
    方法3:V(G) = P + 1,P为判定结点数
    – 环复杂度一般要求在1~10,这样的代码编写良好,有很高的可测试性,维护成本低;
    具有最高环境复杂度的模块蕴含错误的可能性最大,是测试中关注的焦点
  • 基本路径集合并不唯一,但是路径数是确定的;
  • 不是所有基本路径都能够写出测试用例
  • 基本路径集寻找算法:
    Step1:确认从入口到出口的最短基本路径
    Step2:从入口到第一个未被先后评估为真和假两种结果的条件语句
    Step3:改变该条件语句的判断值
    Step4:按最短路径从这个条件语句到出口
    Step5:重复Step2 - 5,直到所有基本路径都被找到
    – 新路径的特点:贯穿程序、引入新的处理语句或者新判断;
  • 测试用例设计过程一览:流程图、流图、环复杂度计算、基本路径、测试用例(一个测试路径覆盖一条基本路径);
  • 为什么流图中会有一个开放的域?——因为基本路径测试理论是建立在程序图是一个强连通图的基础上,因此基本路径测试理论中引入了一条虚拟的从程序出口点指向程序入口点的边,正是这条边构成了最后一个域,即开放域;
  • 基本路径的本质:每一条路径都可以表示为边的向量,即边作为向量的维;
  • 基本路径的数学定义:所谓基本路径,是指一组路径集合,其他任何路径对应的向量,都可以用这些基本路径对应的向量通过线性运算组合出来;基本路径集合不唯一,但大小是由环复杂度唯一确定的;

2.3.10. 基于控制流的测试——循环的处理

  • 循环的四种类型:简单循环、嵌套循环、串接循环、非结构循环;
  • 简单循环的测试用例构造:
    1、跳过整个循环;
    2、只执行一次循环;
    3、执行两次循环;
    4、执行m(m 5、执行n-1,n,n+1次循环;
  • 嵌套循环的测试用例构造:
    – 方法一:先测试最内层的循环:所有外层循环变量置为最小值;最内层按简单循环测试;
    – 方法二:由里向外,测试上层循环:此层以外的所有外层循环的循环变量取最小值;此层以内的所有嵌套内层循环的循环变量取“典型值”;该层按简单循环测试;
    – 方法三:先测最内层循环;由里向外,测试上一层循环;重复上一条规则,直到所有各层循环测试完毕;对全部各层循环同时取最小循环次数,或者同时取最大循环次数;
  • 串接循环的测试用例构造:
    – 若串接的各个循环互相独立:分别用简单循环的方法进行测试;
    – 若两个循环不独立(第一个循环的循环变量与第二个循环控制相关):把第一个循环看作外循环,第二个循环看作内循环,然后用测试嵌套循环的办法来处理;
  • 非结构循环:这一类循环应该先将其结构化,然后再测试;

2.3.11. 基于数据流的测试

  • 数据流覆盖思想:程序是对数据的加工处理过程,对程序的测试可从数据处理流程的角度进行考虑;数据处理过程对应一定的控制流路径;寻找关于某变量的定义和使用位置,思考程序在运行时该变量的值会如何变化,从而分析Bug产生的原因;
  • 数据流测试原理:根据程序中变量定义和其后变量使用的位置来选择程序的测试路径;
  • 数据流覆盖基础:
    – P:程序;
    – G( P ):程序图,即流图
    – V:变量集合;
    – PATH( P ):P的所有路径集合(此路径为数据流测试路径,不同于前面的路径覆盖的路径);
    定义节点DEF(v, n):在节点n定义了变量v,即变量赋值语句,例如input x 或者 x = 2;
    使用节点USE(v, n):在节点n使用了变量v,例如print x 或者 a = 2 + x;
    – 谓词使用P-use:USE(v, n)位于一个谓词中,即条件判断语句中,例如if x>6;
    – 运算使用C-use:USE(v, n)位于一个运算中,即计算表达式中,例如x = 3 + b;C-use又可以进一步划分为:
    输出使用O-use:变量值被输出到屏幕或打印机;
    定位使用L-use:变量值用于定位数组位置;
    迭代使用I-use:变量值用于控制循环次数;
    – 变量v的定义-使用路径(du-path):给定PATH§中的某条路径,如果定义节点DEF(v, m)为该路径的起始节点,使用节点USE(v, n)为该路径的终止节点,则该路径是v的一条du-path;
    – 变量v的定义-清除路径(define-clear-path/dc-path):如果变量v的某个定义-使用路径,除起始节点外没有其他定义节点,则该路径是变量v的定义-清除路径;
  • 数据流覆盖测试步骤
    – 对于给定的程序,构造相应的程序图
    – 找出所有变量定义-使用路径
    – 考察测试用例对这些路径的覆盖程度,即可作为衡量测试效果的度量值
  • 对某一个变量进行数据流测试:
    分析定义节点和使用节点:统计变量出现次数、分析每次出现的节点类型;
    列举可能的DU路径可能出现的路径数 = 定义节点的数量 * 使用节点的数量列出DU路径约简DU路径(约简掉可被覆盖的路径)
    设计测试用例:对约简得到后的DU路径设计测试用例;
  • 数据流覆盖常用标准(不考虑):
    – Rapps和Weyuker标准;

UNIT-3 黑盒测试

3.1. 基本概念

  • 定义:一种基于规格说明,不要求考察代码,以用户视角进行的测试
  • 其他称谓:功能测试、基于规格说明的测试;
  • 意义:有助于软件产品的总体功能验证:检查明确需求和隐含需求、采用有效输入和无效输入、包含用户视角;
  • 实施者:专门的软件测试部门、有经验的测试人员
  • 步骤:规格说明书、生成测试用例、执行测试、判定测试结果;
  • 为什么需要黑盒测试:有时无法获取代码、······;

3.2. 黑盒测试面临的挑战

  • 黑盒测试面临的挑战:编码逻辑未知
  • 问题:代码不可见的前提下,面对未知的缺陷,如何设计测试用例?
  • 解决方法1:随机测试;
  • 解决方法2:在适当的方法的指导下,基于需求规格说明书设计测试用例,既要有正面测试,也要有负面测试,需要更强的技术和耐心来精心设计;

3.3. 随机进行黑盒测试

  • 优点:均匀选取可能的输入值、避免选择偏见、对所有输入一视同仁;
  • 缺点:程序缺陷分配并不均匀、随机测试很难取到特定值;

3.4. 黑盒测试方法基础

3.4.1. 基于需求的测试

  • 目的:确认软件需求规格说明书列出的需求;
  • 前提:需求规格已经仔细评审、隐含需求明确化;
  • 需求跟踪矩阵(RTM):
    – 作用:可跟踪每个需求的测试状态而不会遗漏任何需求、优秀执行优先级高的测试用例(尽早发现高优先级区域内的缺陷)、可导出特定需求对应的测试用例清单、评估测试工作量和测试进度的重要数据;
    – 信息:
    测试指标:按优先级分类的需求数、按需求分类的测试用例数、已设计的测试用例数;
    测试数据采集指标:已通过的测试用例总数、未通过的测试用例总数、需求中的缺陷总数、已完成的需求数、挂起的需求熟;

3.4.2. 正面和负面测试用例

  • 正面测试:测试用例通过一组预期输出验证产品需求;证明软件对于每条规格说明和期望都能通过;需要根据规格说明设计测试用例;
  • 负面测试:测试条件都在需求规格说明之外(负面测试用例不能映射到需求);为了通过未知条件搞垮软件;需要高度创造性产生尽可能多的未知条件;

3.5. 黑盒测试方法

3.5.1. 等价类划分法

  • 等价划分基础:有效等价类和无效等价类;
  • 等价划分准则:
    – 输入条件是布尔表达式,则可以定义一个有效等价类(Ture or False)和一个无效等价类(取反)
    – 输入条件代表一个范围,则可以定义一个有效等价类(正确取值范围)和两个无效等价类(大于和小于)
    – 输入数据个数有规定,则可以定义一个有效等价类(正确的数据个数)和两个无效等价类(大于和小于)
    – 输入条件代表集合的某个子集,则可以定义一个有效等价类(正确的集合取值)和多个无效等价类
    – 输入条件代表要求符合某几个规则,则可以定义多个有效等价类(符合某个规则的输入数据为一个等价类)和若干个无效等价类(用正则表达式表示规则)
    – 输入条件代表一组列表形式的数据(需分别处理的一组输入数据),可以定义N个有效等价类(每个输入数据为一个等价类)和一个无效等价类
  • 等价划分方法步骤:
    Step1:选择划分准则(范围、取值、布尔、集合···);
    Step2:根据准则确定有效等价类无效等价类
    Step3:从等价类中选取样本数据
    Step4:根据需求写预期结果;
    Step5:加入特殊值;
    Step6:执行测试;

3.5.2. 边界值分析法

  • 软件的两个主要缺陷源:条件(变量取值需要采取的特定行动)、边界(各种变量值的极限);
  • 边界值分析:能有效捕获出现在边界处的缺陷的一种测试方法;利用并拓展了缺陷更容易出现在边界处的概念;
  • 缺陷出现在边界处的原因:使用比较操作符时未仔细分析、多种循环和条件检查方法引起的困惑、对边界附近需求的理解不够;
  • 测试边界:测试临近边界的有效数据,测试最后一个可能有效的数据,同时测试刚超过边界的无效数据,例如第1个减1/最后1个加1、开始减1/完成加1、最小值减1/最大值加1;
  • 边界条件类型:
    – 数据类型:数值、地点、位置、字符等;
    – 特征:空/满、最大/最小、第一个/最后一个等;
    – 一些特殊的边界值:Int、Long、unsigned int整数的最小最大值,循环的开始、结束,屏幕光标/鼠标的左上角、右下角等;
  • 如何界定边界值:
    – 字符(根据长度):边界值附近数据——Min-1、Min、Min+1、Max-1、Max、Max+1,例如允许输入1-255个字符则测试用例为0、1、2、254、255、256;
    – 数值范围:边界值附近数据——Min-1、Min、Min+1、Max-1、Max、Max+1,例如输入数据允许1-999则测试用例为0、1、2、998、999、1000;
    – 集合、空间:边界值附近数据——0、Min、Min+1、Max-1、Max、Max+1,例如图片大小不能超过50k则测试用例为0、1k、49k、50k、51k;
  • 边界值附近数据的确认方法:
    n:存在边界值的参数个数;m:边界值条件数;
    Paul Jorgensen公式(3种方法的测试力度依次增强):
    【4n+1】基本边界测试:每个参数取Min、Min+1、Max-1、Max各一次,同时其他参数取典型值;最后全部参数取典型值一次;(例题在Unit3P63)
    【6n+1】健壮性边界测试:每个参数取Min-1、Min、Min+1、Max-1、Max、Max+1各一次,同时其他参数取典型值;最后全部参数取典型值一次;(例题在Unit3P65~P69)
    【3m】条件边界测试:每个条件取-1,自身,+1各一次;每次只考虑一个参数的边界,固定其他参数,最后再补充确定的关联边界值(例题在Unit3P64);
  • 次边界条件/隐形边界:产品说明书中没有,外部用户看不到;
  • 边界值分析总结:
    – 边界值需要彻底测试;
    – 考虑资源极限,如有限的缓存;
    – 需求规格中对硬件资源的限制;
    – 输出值的边界也需要考虑;

3.5.3. 关于等价划分和边界值分析

  • 等价类划分时,往往先要确定边界值;
  • 边界值分析是等价类划分方法的补充;
  • 测试中需要将二者结合起来使用;
  • 等价类划分一定要考虑全面,分为有效等价类和无效等价类,并统一编号
  • 写测试用例时,每个等价类至少有一个测试用例
  • 边界值分析可考虑边界值和条件值
  • 边界值要考虑需求的限制、数据类型的限制、系统的限制等多种限制条件

3.5.4. 因果分析法

  • 因果分析法背景:多个输入条件的关联问题,若用组合测试将面临处理大量测试用例的实现,如火车票价查询是由终点、车次、硬座/卧铺、普通票/学生票等多个因素决定,包裹费用计算是由快递公司、重量、距离等多个因素决定;
  • 因果图:将导致问题的原因划分为多种因素,并描述这些因素间的关系,从而找出问题根源的复杂问题分析工具;
    – 原因和结果的4种关系【C表示原因、E表示结果】:
    恒等(—):若Ci出现,则Ei出现;若Ci不出现,则Ei也不出现;
    非(~):若Ci出现,则Ei不出现;若Ci不出现,则Ei出现;
    或( ∨ \lor ):若几个Ci中有一个出现,则E出现;若几个Ci都不出现,则E不出现;
    并( ∧ \land ):若几个Ci都出现,则E出现;若其中一个Ci不出现,则E不出现;
    – 4种输入约束:
    互斥(E):多个原因不能同时成立,最多有一个能成立,即不能同时为1;
    包含(I):多个原因中至少有一个必须成立,即不能同时为0;
    唯一(O):多个原因中必须有一个且只有一个成立,即只有一个为1;
    要求(R):当C1成立,C2也必须成立;
    – 1种输出约束:
    屏蔽(M):当E1是1时,E2必须是0;E1当是0时,E2必须是1;
  • 因果分析法基础:
    – 原理:软件的输入、输出之间存在逻辑关系,即因果图(可从规格说明书中获得);
    – 过程:根据规格说明书生产因果列表,根据起因结果列表建立决策表,最后利用决策表生成测试用例;
  • 因果图列表:原因的所有组合以及相应的结果组合,所以表中一共有列,其中n为原因的个数(注意:某些原因的组合不存在);
  • 生成决策表:原因即为决策表中的条件,结果即为决策表中的行动,原因与结果的组合即为决策规则;
  • 生产测试用例:决策表中的条件即为测试用例的输入条件、测试用例的期望输出即为决策表中的行动、一条决策规则即为一个测试用例;
  • 因果分析法步骤总结为:
    – 分析规格说明书,识别原因和结果;
    – 在因果图链接原因和结果(可能产生中间条件、结果);
    – 表明原因之间以及结果之间的约束条件;
    – 因果图转换为因果图列表进而生成决策表;
    – 决策表的规则转换为测试用例;

3.5.5. 决策表方法

  • 决策表并非因果图的一个辅助工具;
  • 原理:
    – 适用情形:输入输出较多且输入之间和输出之间相互制约的条件较多;
    – 决策表:把作为条件的所有输入的组合以及对应输出都罗列出来形成的表格
    – 特点:能将复杂问题按照各种可能情况全部列出,表示简明扼要,并避免遗漏;
  • 决策表组成:
    – 条件桩:列出所有可能问题(条件);
    – 条件项:列出条件所有可能取值;
    – 动作桩:列出可能采取的操作;
    – 动作项:指出在条件项的各种取值情况下应采取的动作;
    – 决策规则:贯穿条件项和动作项的一列;
  • 构造决策表(规则可能总数为2n):
    – 列出所有的条件桩和动作桩;
    – 填入条件项;
    – 填入动作项,得到初始决策表;
    – 简化决策表,合并相似规则;
  • 简化决策表:有两条或以上规则具有相同动作,并且在条件项之间存在极大相似,便可以合并,用“—”表示合并后改条件项与取值无关,称为“无关条件”

3.5.6. 因果图和决策表

  • 能够列出原因和结果列表;
  • 因果图的画法(会读图);
  • 根据因果图得出因果列表,进一步得出决策表;
  • 决策表约简;

3.5.7. 因果图和决策表

  • 模型:模型即理解复杂系统的工作过程、解释没有完全理解的事物、将抽象的事物变具体;建模过程迫使我们将复杂的事物分解成许多清晰而且易于理解的单元,最终让我们更好地理解整个问题;
  • 基于模型的测试原理:软件执行过程可分解为若干对象和连接对象间的关系;测试序列可视为验证对象间所希望的关系是否满足;
  • 适用领域:有限状态建模;工作流建模;数据流建模;时间建模;

3.5.8. 正交数组测试

  • 背景:在测试中,特别是互联网应用,我们无法规定用户的环境,分布在世界各地的用户其使用的环境是各种各样的,操作系统有Windows XP、Windows 7~10、macOS X、Linux等等,浏览器有IE 6.0、IE 7.0、Fire Fox 1.5、Fire Fox 2.0、Safari等等,传输协议有TCP、TDP、HTTP、HTTPS、SSL等等,代理服务器/防火墙有ISA 2000、ISA 2004、Blue Coast等等,语言有中文简体、中文繁体、英文、日文、德文等等,如果用一个完全的组合那将是一个爆炸性的组合,测试工作量将会非常大,为每个组合产品的功能设计的测试用例的综合可能达到上亿个;;
  • 正交试验设计方法:
    – 正交试验设计方法是从大量的实验数据中挑选适量的、有代表性的点,从而合理地安排测试的一种科学的试验设计方法;
    – 数学家们已经为我们打造好了正交表,所以我们可以使用已经造好了的表格——正交表来安排试验并进行数据分析;
    正交试验设计是研究多因素多水平的一种设计方法,它是根据正交性从全面试验中挑选部分具有代表性的点进行试验,这些具有代表性的点具备了“均匀分散,齐整可比”的特点;
  • 原理:
    – 从大量测试用例中挑选适量的、有代表性的用例,从而合理地进行测试的方法;
    – 使用领域:输入域相对较少而详尽测试的次数又过大的问题;
    – 特点:输入域有限,参数取值有限,需要将参数取值进行排列组合;
  • 正交表:
    – 构成:
    因子(Factor):欲考察的变量因素(输入参数);
    水平(Level):单个因子的取值(输入取值)
    因子数(Factors):正交表中列的个数
    水平数(Levels):单个因子的取值个数
    行数(Runs)正交表行数,即测试用例个数;
    – 正交表的形式:
    记法:L行数(水平数因子数)
    正交表可以通过查表或者软件辅助来构造;
    – 正交表的正交性:
    整齐可比性:在同一张正交表中,每个因子的每个水平出现的次数是完全相同的。每个因子的每个水平与其他因子的每个水平参与试验的机率是完全相同的,这就保证在各个水平中最大程度排除了其他因子水平的干扰;
    均衡分散性:在同一张正交表中,任意两列(两个因子)的水平搭配(横向形成的数字对)是完全相同的。这样就保证来了试验条件均衡地分散在因子水平的完全组合之中,因而具有很强的代表性,容易得到好的试验条件。
    – 如何得到正交表:正交表可以通过查表活着软件辅助来构造;
  • 正交数组测试步骤
    确定因子和水平:有哪些因子?总因子数是多少?每个因子有哪些取值?其水平数是多少?
    判断是否能使用正交数组:因子的个数少,如只有2个,则不适用;因子的个数较多时可考虑正交数组;
    选择合适的正交表:根据因子数和水平数选择测试次数最少的正交表;
    把变量值映射到表中:填入输入变量的取值;
    正交测试用例制作:每一行对应一个测试用例;
    补充测试用例:根据需求规则说明书,增加一些正交表没有覆盖但需要测试的用例;
  • 选择正交表的原则:
    考虑因子的个数:正交表因子数>=实际因子数
    考虑因子的水平个数:正交表每个因子水平数>=实际每个因子水平数
    考虑正交表的行数:如果出现2个或2个以上正交表符合以上条件,则选择行数最少的正交表
    若没有和对应因子数对应的表:取因子数最接近但略大的实际值的表;例如5因子2水平则选择L8(27)而不是L16(215);
    若因子的水平数不同:采用包含和组合的方法选择合适的正交表,即取最大水平数、因子数包含因子总数的正交表,选取了正交表后,删除正交表中多余的因子列,原则是删除靠后的列;例如在4个因子中包含1因子4水平3因子3水平则选择L16(45);

3.5.9. 蜕变测试

  • 查阅互联网

3.6. 黑盒测试总结

  • 特点:被测软件内部逻辑未知的测试方法总称;
  • 目的:功能的正确和遗漏;界面错误;数据访问;性能;初始化和终止;
  • 技术:基于需求的测试;正面测试和负面测试;边界值分析;因果分析法;决策表;等价类划分法;基于图/状态的测试;正交数组测试;
  • 插桩:实现白盒测试和黑盒测试的支持技术;

3.7. 灰盒测试

  • 定义:基于程序内部细节有限认知的软件调试方法;测试者可能知道系统组件之间的相互作用,但缺乏对内部程序功能和运作的详细了解;对内部细节的有限了解有利于设计更好的测试用例;
  • 白盒测试VS黑盒测试VS灰盒测试:
    【SEU&SE】软件测试及应用课程笔记_第4张图片

3.8. 黑盒测试工具

  • 主流的黑盒测试工具有哪些?测试工具如何使用?

3.8.1. 功能测试工具

  • 特点:是黑盒测试工具;软件测试工具中最活跃的类型;多用于系统测试、确认测试和回归测试;以自动化测试工具为主;
  • 功能:
    – 录制和回放:录制即测试输入的自动化、回放即重新执行测试用例;
    – 检验:即设置监测点、对用例执行的正确性进行检查;
    – 可编程:即脚本更加灵活、功能更加强大;
  • 自动化测试工具原理:运行被测软件的同时,捕获过程中的键盘、鼠标操作,生成脚本文件,这个脚本文件可以进行修改和回放;
  • 主流功能测试工具:
    – Quick Test Professional(QTP):创建功能和回归测试;自动捕获、验证和重访用户的交互行为;为每一个重要软件应用和环境提供功能和回归测试自动化的行业最佳解决方案;
    – Rational Robot:一种对环境的多功能的、回归和配置测试工具;可测试众多类型的应用;
    – SilkTest:是面向Web应用、Java应用和传统的C/S应用,进行自动化的功能测试和回归测试的工具;提供了用于测试的创建和定制的工作流设置、测试计划和管理、直接的数据库访问及校验等功能,使用户能够高效率地进行软件自动化测试;
    – AutoRunner:可进行Web测试和.NET测试;是黑盒测试工具,可以用来完成功能测试、回归测试、每日构建测试与自动回归测试等工作。是具有脚本语言的、提供完善的针对脚本跟踪和调试功能的、支持IE测试和Windows测试的自动化测试工具;

UNIT-4 单元测试与集成测试

4.1. 单元测试

4.1.1. 软件单元

  • 一个应用程序中的最小可测部分
  • 面向过程中的单元:单独的程序、函数、过程、网页、菜单…;
  • 面向对象中的单元:类(基类、抽象类、子类);

4.1.2. 基本概念

  • 【定义】单元测试/模块测试:对最小的软件设计单元(模块/源程序单元)的验证工作;
  • 意义:消除软件单元本身的不确定性、是其他测试阶段的必要的基础环节;
  • 实施者:软件开发人员;
  • 测试目标:
    – 单元体现了预期的功能
    – 单元的运行能够覆盖预先设定的各种逻辑
    – 单元工作中:内部数据能够保持完整性;
    – 可以接受正确数据,也能处理非法数据
    – 在数据边界条件上,单元能正确工作;
    – 单元的算法合理,性能良好;
    – 扫描单元代码没有发现任何安全性问题;
    – ……
  • 测试关注点:模块功能、内部逻辑处理、数据结构、性能、安全;
  • 测试技术和步骤:
    – 白盒测试技术:使用一种或多种白盒测试方法分析模块的逻辑结构;
    – 黑盒测试技术:使用黑盒测试方法对照模块的规格说明以补充测试用例;
    – 步骤:先设计测试用例,然后执行测试;
  • 进入和退出条件:
    进入条件:编码开始:设计测试用例数据并执行测试
    退出条件:完成测试计划、发现并修正了错误、预算和开发时间

4.1.3. 单元测试考虑事项

  • 模块或构件接口:
    – 目标:进出模块/构件的数据流正确
    – 关注点:接口名称、参数个数、类型、顺序的匹配;输出或返回值及其类型是否正确;
    – 测试接口正确与否应该考虑下列因素:
    输入的实际参数与形式参数的个数是否相同、属性是否匹配、量纲是否一致;
    调用其他模块时所给实际参数的个数、属性、量纲是否与被调用模块的形参个数相同、属性匹配、量纲一致;
    调用与定义函数时所用参数的个数、属性和次序是否正确;
    是否存在与当前入口点无关的参数引用;
    是否修改了只读型参数;
    ……
    – 如果模块内包括外部输入输出,还应该考虑下列因素:
    文件属性是否正确;
    格式说明与输入输出语句是否匹配;
    缓冲区大小与记录长度是否相匹配;
    文件使用前是否已经打开、使用后是否关闭;
    ……
  • 局部数据结构:
    – 目标:数据在模块执行过程中都维持完整性和正确性
    – 关注点:数据结构定义和使用过程的正确性;局部数据结构对全局数据结构的影响
    – 对于局部数据结构,单元测试要发现:
    不合适或不相容的类型说明;
    变量无初始值;
    变量初始化或省缺值有错;
    不正确的变量名;
    出现上溢、下溢和地址异常;
    – 同时还应该查清全局数据对模块的影响:
  • 边界条件:
    – 目标:保证模块在条件边界上能够正确执行(如数组a[n])
    – 关注点:数据结构中的边界;控制流中的边界(如循环次数、判断条件)
  • 独立路径:
    – 目标:保证模块中的每条独立路径(基本路径)都要走一遍,使得所有语句都被执行过一次
    – 关注点:对路径的选择性测试(基本路径测试+循环测试)
    – 测试用例应发现的错误:
    在不同数据类型间进行比较;
    不正确的逻辑操作或优先级;
    由于精度错误,该相等的地方不能相等;
    不正确的变量;
    不正常的循环终止;
    循环不能退出;
    循环变量修改错误;
  • 处理错误的路径:
    – 目标:保证错误处理的正确性、软件的健壮性;好的软件设计要求错误条件是可预知的,并且当错误发生时,错误处理路径被建立,以重定向或终止处理;
    – 错误处理关注点:
    输出的出错信息难以理解;
    记录的错误与实际遇到的错误不相符;
    在程序自定义的出错处理段运行之前,系统已经介入;
    异常处理不当;
    错误陈述中未能提供足够的定位出错信息;

4.1.4. 单元测试规程

  • 驱动器和程序桩:
    – 绝大多数情况中,单个单元是不能正常工作的,而是要和其他单元一起才能正常工作,所以实际测试活动中的普遍问题是「其他单元不存在的情况下如何运行单个模块?」;
    – 单元测试通常与编码工作结合起来进行;
    – 模块本身不是一个独立的程序,在测试模块时,必须为每个被测模块开发一个驱动器(driver)和若干个桩程序(stub);
  • 驱动器(Driver):对底层或子层模块进行测试时所编制的调用被测模块的程序,用以模拟被测模块的上级模块;即接受测试数据,并把数据传送给被测模块,最后输出相关结果;
    – 驱动器结构:数据说明、初始化、输入测试数据、调用被测模块、输出测试结果、停止;
  • 桩程序(Stub):对上层模块进行测试时,所编制的代替下层模块的程序,用以模拟被测模块工作过程中所调用的下级模块;即模拟未被测试模块/隶属模块的功能;
    – 插桩:为获取特定的测试信息而添加进程序的测试操作;
    – 桩程序结构:数据说明、初始化、输出提示信息(表示进入了哪个桩模块)验证调用参数,打印验证结果、将模拟结果送回被测程序、返回;
  • 高内聚性程序:驱动器和程序桩简单,错误容易被发现;
  • 低内聚性程序:驱动器和程序桩工作量大,某些白盒测试需要推迟到集成测试阶段;
  • 手工和自动化测试:
    – 手工测试:按照需求规格设计测试用例完成测试;静态测试;
    – 自动测试:自动化方法的效果:有效验证较为独立单元的正确性;
  • 单元测试驱使程序员创建低耦合、高内聚的代码体,有助于开发健壮的软件
  • 单元测试局限性:只验证单元自身的功能,不能捕获系统范围的错误(系统错误、继承错误、性能问题等);被测模块实现中可能接受的所有输出情况难以预料;

4.2. 集成测试

  • 把单独的软件模块结合在一起做为整体接受测试;

4.2.1. 基本概念

  • 意义:验证软件单元间能否协调工作;验证单元集合的功能、性能和可靠性需求;
  • 实施者:软件测试人员+软件开发人员;
  • 测试技术:黑盒测试技术为主,白盒测试技术为辅;
  • 步骤:与集成测试策略相关;
  • 进入条件:设计阶段:测试场景和测试数据;编码阶段:若干模块由继承需求时便执行测试;
  • 退出条件:完成测试计划、发现并修正了错误、预算和开发时间;
  • 必要性:接口连接问题:函数相互调用、模块间的互相影响、单个模块中的缺陷发生扩散、全局数据结构……;
  • 三种进行集成测试的情形:由若干单元/就模块组成一个构件、由若干构件组成一个工件、由若干工件组成为一个系统;
  • 集成测试目标:集成测试用来构造程序并实施测试以发现与接口连接有关的错误,它把经过单元测试的模块拿来,构造一个在设计中所描述的场景;
  • 接口:
    – 内部接口:产品内部两模块之间通信的借口;
    – 外部接口:产品之外第三方可以看到的接口;
    – 接口提供方法:API、SDK;
    – 桩程序:以合适的格式提供合适的值,模拟实际组件;
    – 显式接口:写入文档的明确化接口;
    – 隐含接口:未写入文档、只有开发人员知道;

4.2.2. 集成测试策略(如何进行集成测试)

  • 瞬时集成测试:又称大爆炸测试策略
    – 特点:当所有构件都通过单元测试,就把它们组合成一个最终系统,并观察它是否正常运转;
    – 缺陷:无休止的错误:错误很多、错误修复很困难、修正错误后新的错误马上出现;模块一次性结合,难以找出错误原因;接口错误和其他错误容易混淆;
    – 只适用于小型软件开发;
  • 增量集成测试
    – 特点:将程序分成小的部分进行构造和测试;
    – 优点:错误容易分离和修正、接口容易进行彻底测试;
    – 缺点:会有额外开销,但能大大减少发现和修正错误的时间;
    – 三种增量集成测试:
    1. 自顶向下集成:
      – 集成顺序:首先集成主模块(主程序),然后按照控制层次向下进行集成;
      – 集成方式:深度优先(一层一层集成)、广度优先(直接集成到最底下然后再返回上一层);
      – 集成步骤:
      (1) 主程序做为测试驱动器;
      (2) 根据集成顺序,程序桩逐渐被各模块替换
      (3) 每个模块集成时都需要进行测试;
      (4) 每完成一次测试后,将新模块替换程序桩
      (5) 利用回归测试来保证没有引进新的错误;
      – 优点:尽早发现高层控制和决策错误最多只需要一个驱动器;每步只增加一个模块;支持深度优先和广度优先;
      – 缺点:对低层模块行为的验证比较晚;需要编写额外程序模拟未测试的模块;部分测试用例由于依赖于其他层次的模块,在该模块未测试之前,这些测试用例的输入和输出很难确定;必须开发桩模块
      – 实施的主要难点:对于高层测试需要在底层测试完成后才可以进行的情形难于编写桩模块
      – 解决方法:推迟测试直到底层模块完成测试;设计程序桩模拟底层模块;自底向上测试;
    2. 自底向上集成
      – 集成顺序:从原子模块,即程序最底层模块开始就构造并进行集成测试;即从原子模块到造件(Build)再到应用软件系统;
      – 集成步骤:
      (1) 底层模块组成实现特定子功能的造件;
      (2) 编写测试控制程序协调输入输出;
      (3) 测试特定子功能的造件;
      (4) 沿层次向上对造件进行组合;
      – 优点:尽早确认底层行为;无需编写程序桩;对实现特定功能的树容易表示输入输出;如果主要的缺陷发生在程序的底层将非常有利;测试环境比较容易建立;
      – 缺点:推迟确认高层行为;需编写驱动器;组合子树时,有许多元素要进行集成;直到最后一个模块添加进去后程序才能形成一个整体;
    3. 混合式集成:
      – 集成顺序:综合自顶向下和自底向上,是实际测试中的实用集成测试策略;
      – 特点:开发小组对各自的底层模块向上集成、专门的集成小组进行自顶向下集成;
      – 步骤:
      (1) 用程序桩独立测试上层模块;
      (2) 用驱动器独立测试底层模块;
      (3) 集成时对中间层进行测试;

4.2.3. 集成测试方法选择指南

【SEU&SE】软件测试及应用课程笔记_第5张图片

4.2.4. 集成测试总结

  • 集成测试是一个必要的测试阶段:从将两个组件集成到一起开始,到所有系统组件在一起运行位置的所有测试活动,都是集成测试阶段的一部分;
  • 集成测试是一种测试类型:集成测试测试组件间的接口;
  • 集成测试不应被淡化:集成测试能减少系统测试阶段的缺陷;

4.3. 测试插桩(Instrumentation)

4.3.1. 背景

  • 测试过程中,往往需要知道某些信息,例如程序中可执行语句被执行(即被覆盖)的情况、程序执行的路径、变量的使用和定义,传统的方法是跟踪被测程序的执行过程,人工收集信息;
  • 程序插桩技术是在保证被测程序原有逻辑完整性的基础上在程序中插入一些探针,通过探针的执行并抛出程序运行的特征数据,通过对这些数据的分析,可以获得程序的控制流和数据流信息,进而得到逻辑覆盖等动态信息,从而实现测试目的的方法

4.3.2. 原理

  • 在程序特定部位附加一些操作或功能,用来检验程序运行结果以及执行特性,以便支持测试;

4.3.3. 两类插桩技术

  • 白盒测试插桩技术和黑盒测试插桩技术;

4.3.4. 插桩方式

  • 目标代码插桩:
    – 优点:目标代码的格式主要和操作系统相关,和具体的编程语言及版本无关,应用范围广;特别适合需要对内存进行监控的软件中;
    – 缺点:目标代码中语法、语义信息不完整;
  • 源代码插桩:
    – 优点:词法分析和语法分析的基础上进行的,这保证了源文件的插桩能够达到很高的准确度和针对性;
    – 缺点:作业量大,而且随着编码语言和版本的不同需要做出一定的修改;

4.3.5. 白盒测试插桩技术

  • 探测什么信息:由具体需求而定,如覆盖率、中间结果、测试数据生成、统计信息等;
  • 插桩位置:由具体需求而定;原则上探针的植入要做到紧凑精干,才能保证在做到收集的信息全面而无冗余,减少代码的膨胀率;可能植入的位置有程序的第一条语句、分支语句的开始、循环语句的开始、下一个入口语句之前的语句、程序的结束语句、分支语句的结束、循环语句的结束等等;
  • 插桩策略
    语句覆盖插桩(基本块插桩):在基本块的入口和出口处,分别植入相应的探针,以确定程序执行时该基本块是否被覆盖;
    分支覆盖插桩:分支由分支点确定。对于每个分支,在其开始处植入一个相应的探针,以确定程序执行时该分支是否被覆盖;
    条件覆盖插桩:if,switch,while,do-while,for几种语法结构都支持条件判定,在每个条件表达式的布尔表达式处植入探针,进行变量跟踪取值,以确定其被覆盖情况;
  • 探测点数目:个数越少越好,插桩会影响原有程序执行的效率;
  • 如何在程序中特定部位插入语句:可以在程序中特定部位插入某些用以判断变量特性的语句(断言,assert(expression)),使得程序执行中这些语句得以证实;
  • 断言语句(assert(expression))的缺点:频繁的调用会极大影响程序性能,增加额外的开销;每个assert只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败;
  • 作用:生成特定状态,检验状态的可达性;显示或读取内部数据或私有数据;检测不变数据;检测前提条件;人为触发事件时间;检测事件时间;

4.3.6. 黑盒测试插桩技术

  • 测试预言(Test Oracle)
    – 定义:一种独立于被测系统的程序或机制,用于确认对于给定输入,系统是否有一个给定输出;
    – 特点:不能获得源代码,但可以调用API等信息,不属于纯黑盒测试,而是一种灰盒测试
    – 作用:检查函数正确性、系统安全性、…
  • 随机数据生成(随机测试技术)
    – 定义:一种在可能输入集中选取一个任意子集进行测试的技术;
    – 作用:避免只测试所知道的将奏效的场景
    – 有效测试用例生成方法:软件输入域进行等价划分、各子域边界进行边界值选取、各子域内进行随机测试选择输入样本;

4.4. 单元/集成测试工具(略)


UNIT-5 J-Unit(略)


UNIT-6 系统测试、确认测试、回归测试

6.1. 系统测试

6.1.1. 基本概念

  • 定义:对完整集成后的产品和解决方案进行测试,用来评价系统对具体需求规格说明的功能和非功能的符合性的测试
  • 目的/作用:发现可能难以直接与模块或接口关联的缺陷;发现产品设计、体系和代码的基础问题(产品级缺陷)
  • 引入时机:集成测试之后(基础的程序逻辑错误和缺陷已更正后);
  • 实施人员:独立测试团队(引入独立视角,有助于发现遗漏缺陷)
  • 特点:是既测试产品功能也测试产品非功能的唯一测试阶段
  • 实施原因:
    – 在测试中引入独立视角;
    – 在测试中引入客户视角;
    – 在测试中模拟客户使用环境;
    – 测试产品功能和非功能的问题;
    – 建立对产品的信息;
    – 分析和降低产品发布的风险;
    – 保证满足所有需求,产品具备交付确认测试条件;
  • 系统测试 = 功能测试 + 非功能测试;

6.1.2. 系统测试VS组件和集成测试

  • 系统测试是对其他阶段测试的互补性测试;
  • 组件和集成测试主要关注技术和产品实现,而客户场景和使用模式是系统测试的基础,系统测试有助于将关注点从产品开发团队转移到客户及其对产品的使用上;

6.1.3. 功能系统测试

  • 为什么还要进行功能系统测试:
    – 在系统测试阶段主要进行产品级的功能测试;
    – 进行功能系统测试,可以覆盖前面各阶段均遗漏的测试;
    – 在各个阶段,由不同的人不同的团队进行功能测试,有助于从不同视角发现新的缺陷;
  • 功能系统测试方法:
  1. 设计/体系结构测试
    – 原理:对照设计和体系结构开发和检查测试用例,从而整理出产品级测试用例;集成测试用例关注模块或组件间交互,而功能系统测试用例关注整个产品的行为;从产品角度出发,检查软件体系结构的总体拓扑结构、构件模型的结构是否合理?构件的接口和连接件的角色是否匹配?是否满足相应的约束?
    – 静态测试:即体系结构分析,对体系结构的特征进行建模、分析,如对类定义的一致性分析;
  2. 业务垂直测试
    – 原理:针对不同业务纵深的产品,根据业务定制测试用例,验证业务运作和使用;
    – 应用范围:通用的工作流自动化系统在不同商业领域的应用;
    – 方法:
    模拟:测试需求和业务流;
    复制:获取客户数据和过程,针对特殊业务进行定制
    定制:改变系统的一般工作流,以适用于不同业务纵深;
    术语:尽量使用各业务领域的专属名词;
  3. 部署测试
    – 验证系统是否能满足客户的部署需求;
    – 目的;特定产品版本短期内是否能成功使用;
    – 离场部署:在产品开发组织内进行,确保客户部署需求的(模拟)部署测试;
    – 现场部署(离场部署的扩展):现场部署是指在客户场地中的资源和环境都发布后,实施的一种部署方案;采集实际系统真实数据以建立镜像测试环境,重新执行用户操作,然后引入新产品,进行新业务操作,同时对比事务处理情况,以确定新系统是否能够代替老系统;
  4. Alpha测试和Beta测试
    – Alpha测试:
    定义:用户在开发环境下进行的受控测试;
    特点:不由程序员或测试员完成,但开发者会在现场;
    在Alpha测试达到一定程度后进行Beta测试;
    – Beta测试:
    定义:用户在实际使用环境下进行测试,是一种可以把待测产品交给用户收集反馈信息的机制;
    特点:开发者通常不在现场;
    挑战:客户数量、客户是否充分了解产品;
  5. 符合性的认证、标准和测试
    – 产品需要通过主流硬件、操作系统、数据库和其他基础设施构件上进行的验证,并符合相关法规和行规;

6.1.4. 非功能系统测试

  • 非功能系统测试用于验证系统的质量因素,要求理解产品行为、设计和体系结构,针对不同配置和资源对产品进行测试,并收集和分析相应数据,评判产品质量;
  • 最大挑战:设置配置;因为难以预测客户使用的环境,对配置进行组合测试的代价太高,建立测试环境成本高,很难准确预测客户使用的数据;
  • 设置配置的两种方法:模拟环境和真实客户环境;
  • 方法:
  1. 性能测试:为了获取或验证系统性能指标而进行的测试;评价响应时间、吞吐率和系统的使用情况,执行所要求的功能以对同一产品的不同版本或竞争产品进行比较;性能测试可使用负载测试的技术和工具
  2. 国际化测试:确保软件支持不同国家语言的测试手段,例如货币格式、日期格式、消息显示等等;
  3. 可伸缩性/容量测试:确认产品参数的最大值,确定产品的主要瓶颈,即某项功能的最大承受能力;
  4. 可靠性测试:在一定时间段内持续不断地测试软件产品,评价该产品在规定时间和条件下,维持其正常的功能操作、性能水平的程度;即评价产品在给定条件下在给定时间段内或多轮迭代内执行所要求功能的能力;可靠性指标:平均失效等待时间(连续失效之间的平均间隔时间)、失效率(风险参数,单位时间内发生的失效次数)、平均发现下k个缺陷的时间(预测下k个缺陷的平均时间);要求具有可恢复性、容错性;
  5. 负载测试(Load Testing):通过模拟实际软件系统所承受的负载条件、改变系统负载大小和负载方式来发现系统中存在的问题
    负载测试VS容量测试:负载测试通过改变系统负载大小和负载方式、增加负载等来发现系统的性能问题;而容量测试是在预先定义(分析)的极限值下,看系统是否能正常工作;考虑到预期业务处理量的增加,容量测试还将确定测试对象在给定时间内能够持续处理的最大负载;
  6. 压力测试:压力来自于系统的极端情况,例如不足的内存、有限的网络带宽、磁盘读写被占用等等;目的是为了评价系统超过所描述的需求或资源限制时的情况,保证系统不崩溃,有助于了解系统在极端和现实环境中的行为,期望随着负载增加产品性能平稳下降,但任何时候都不应该崩溃;压力测试用例可选择重复性测试用例或并发性测试用例或随机测试用例,但负载量级一定要对系统形成压力;压力测试可以看作负载测试的一种,压力测试更强调持续加压,测试系统的极限值
  7. 互操作性测试/兼容性测试:保证两个或多个产品可以交换和使用信息,并恰当地在一起运行;分为前向兼容和后向兼容;
  8. 安全性测试
  9. 可使用性和易获得性测试:可使用性即以用户视点确认产品的易用性、速度和美感的测试,影响因素为可理解性、一致性、导航和响应;易获得性检查产品对于行动不便的用户也可使用的测试;
  • 对比分析:
    可靠性测试保持恒定的负载条件在一定时间内不断持续测试产品,根据结果评价产品的可靠性情况;
    压力测试中负载以各种方式逐步增加,发现压力点,保证系统在超过压力点的情况下不崩溃
    负载测试通过观察不同负载下系统响应时间和数据吞吐量、系统占用的资源等,以发现系统存在的性能瓶颈、内存泄漏等问题;
    容量测试确定不同配置下系统的最大能力,有助于确定产品中的瓶颈;
    性能测试通过自动化测试工具模拟多种正常、峰值及异常负载条件来对系统的各项性能指标进行测试;

6.2. 确认测试

  • 定义:检查产品是否满足项目的需求阶段定义的确认准则,或者说是否具备在真实环境中使用的条件;
  • 实施者:客户或客户代表
  • 引入时机:系统测试之后;
  • 目的:验证和接受产品;
  • 测试用例:测试用例数量较少,目的也不是为了发现缺陷;
  • 测试环境:近似实际场景下执行;
  • 确认准则:产品确认、规程确认、服务等级约定;

6.3. 回归测试

  • 回归测试是一种验证已变更系统的完整性与正确性的测试技术

6.3.1. 背景

  • 捉摸不定的软件:软件不断演化、需求不断变更、技术更新和软硬件升级,而且软件的每次改变都会引入潜在风险——缺陷;
  • 对软件变化的要求:修改后的功能是否达到预期?原有功能是否被损害?

6.3.2. 概念

  • 定义:回归测试是对之前已测试过、经过修改的程序进行的重新测试,以保证该修改没有引入新的错误或者由于更改而发现之前未发现的错误;回归测试要保证增强型或修正型修改使软件正常运行而且不影响已有功能;
  • 意义:保证软件维护时未更改的代码功能不会受到影响;实现软件整个生命周期的测试;保证软件模块区域和持续维护过程与回归测试的协作关系,使回归测试成为一个每月每周每日的常规活动;
  • 引入原则:开发过程发生修改或维护,就有必要进行回归测试,故单元测试、集成测试、系统测试都是引入回归测试的时机;
  • 特点:回归测试时间不包含在进度表中;测试范围为被修改部分正确性一集它与原有功能的整合;只需要测试软件的一部分所以测试时间短;是由系统被修改而出发的周期性活动;
  • 过程:提出软件修改需求、进行软件修改、选择测试用例(获取正确的测试用例)、执行测试(自动化)、识别失败结果、识别错误、排出错误;
  • 策略:全部重新测试(不用进行测试用例选择但不灵活)、有选择地重新测试(灵活实用,但需要耗费精力选择测试用例);
  • 组测试技术:一个模块可能单独工作正常,多个模块集成工作时却出现错误,组测试(Group Testing)是寻找此类错误的有效方法;
  • 波及效应:是为了发现所有受影响部分和发现潜在的受影响部分,以保证软件发生改变后仍然保持一致性和完整性
    波及效应分析步骤【SEU&SE】软件测试及应用课程笔记_第6张图片
    – 共有四种波及效应:需求的波及效应;设计的波及效应;代码的波及效应;测试用例的波及效应;

你可能感兴趣的:(【SEU&SE】软件测试及应用课程笔记)