东南大学《软件测试》课程复习笔记

2020-05-27
惊闻这两天就要安排线上考试,抓紧把之前剩了个尾巴的复习笔记完成了,希望可以取得还OK的成绩。

整理了一下2019-2020学年计算机学院大三下《软件测试》课程的内容,仅供参考。

by z0gSh1u

导论 / Chapter 1

大型软件开发中经常遇到巴别塔和焦油坑(极度混乱、复杂的情况)

什么是错误(error):1+2=5;死机、崩溃…

为什么有错误:Everything & Everyone。软件测试就是为了发现错误以便解决错误。

软件测试过程图

正确的测试策略:尽可能经常测试,并且尽早测试。缺陷发现的越晚,消除的代价就越大。

经典测试理论 / Chapter 2

测试的V模型

提出的四大测试过程:单元测试、集成测试、系统测试、验收测试

问题:错误引入的越早,发现的却越晚。

单元测试

对最小可测试元素(函数、类)进行测试。

  • 模块接口测试:检查进出模块的数据是否正确
  • 模块局部数据结构测试:未使用的变量、数组越界…
  • 模块边界条件测试:合法数据、非法数据…
  • 模块独立执行通路测试:计算错误、判定错误、控制流错误
  • 模块内部错误处理测试:错误处理设施是否有效

集成测试

对单元进行集成后测试。测试对象可以是一个包或一组包。

进行集成的方法

  • 增式

    A → AB → ABC

    特点:工作量小;发现错误早;错误定位容易;测试彻底;需要机器多;并行性差

    • 自顶向下

      高级模块作为驱动,每次替换掉一个低级的stub(桩,临时占位的模块),逐步求精。

      缺点:需要提供stub;stub模块可能难以模拟数据

    • 自底向上

      要编制驱动程序,协调测试用例输入输出。生成测试数据没有困难,适合关键模块在底部的情况。

      缺点:不能尽快看到整个程序的框架;时序和资源竞争问题只能到后期发现

  • 非增式

    特点:工作量大;发现错误晚;错误定位难;测试不彻底;需要机器少;并行性好

    A → B → C → ABC

系统测试

对系统“整体”进行测试,模拟真实运行环境。

验收测试

最后一道工序,用户在场测试,非开发人员和测试人员完成。

  • α测试(内测)

    开发即将完成时进行,可以对程序作小的变动。测试环境受开发方控制,用户的数量少,时间集中。

  • β测试(公测)

    开发基本完成时进行,正式发布前寻找错误。测试环境不受开发方控制,用户的数量多,时间不集中。

测试任务的过程

测试计划

  • 测试目标

    单元测试的目标是检查最小单元有无错误;集成测试的目标是检查模块有无错误…

  • 测试范围(回答“哪些“的问题)

    哪些接口需要测试?哪些要做性能测试?

  • 测试项目

    功能测试;数据库集成测试…

  • 测试策略

    基于代码覆盖;基于规格说明…

  • 测试工具

  • 测试资源

  • 产出物件

测试设计

  • 设计测试用例
  • 设计测试脚本
  • 评估测试覆盖

开发

  • 搭建测试环境
  • 编写测试脚本

执行

  • 执行测试脚本
  • 分析执行情况
  • Bug报告 / Bug跟踪

评估

  • 分析覆盖率(测试用例覆盖、代码覆盖)
  • 分析缺陷
  • 是否达到退出标准
  • 撰写报告

测试方法

  • 静态方法和动态方法

    • 静态分析:检查和阅读
    • 动态方法:运行测试用例
  • 黑盒测试与白盒测试

    • 黑盒测试:不考虑程序内部
    • 白盒测试:分析程序的内部结构
  • 回归测试

    检查修改或增加的部分是正确的,并且没有造成其他错误

  • 模拟用户操作

测试类型

  • 可靠性测试
  • 功能测试
  • 性能测试
  • ……

测试工具

  • 测试管理工具:Quality Center
  • 性能测试工具:Load Runner
  • 单元测试工具:JUnit

黑盒测试 / Chapter 3

将程序当作黑盒,进行总体功能验证

特点:基于规格说明(需求),与代码实现无关,以用户视角进行,适用于测试的各个阶段。

实施工具:需求规格说明;需求跟踪矩阵RTM;测试执行数据

实施策略:正面(预期输入输出)和负面(非预期输入)测试用例

等价类划分

将程序的输入域划分为有效等价类(有效输入数据)和无效等价类(无效输入数据),来导出测试用例。

划分准则

下表描述了一些输入数据类型的等价类划分思想:

例子:

合法的用户名要求:
(1)由字母开头;(2)后跟字母或数字的任意组合构成;(3)有效字符数不超过6个

2个有效等价类:
(1){0<全字母<=6}:John, Kenedy
(2){0<字母开头+数字<=6}:u001, user01

4个无效等价类:
(1)字母串,且长度超过6:userabcd
(2)字母开头的字符、数字组合串,且长度超过6:user01587
(3)长度不超过6的数字开头串:010ah
(4)其他:数字开头的字符串集合、空字符串、非法字符串

因果图(判定表)

多个输入条件互相关联、存在逻辑关系时,组合测试可能生成大量无效的测试用例。

因果的四种关系

四种输入约束,一种输出约束

输入:

  • 互斥:最多只有一个成立
  • 包含:至少一个成立
  • 唯一:有且只有一个成立
  • 要求:有向,C1成立则C2成立

输出:

  • 屏蔽:有向,E1成立则E2不成立

根据因果图,可以快速排除一些不可能的输入,和一些不可能的输入输出组合。

边界值分析

利用并扩展了缺陷更容易出现在边界处的概念。

等价类划分时,往往先要确定边界值。边界值分析是等价类划分方法的补充,测试中需要将两者结合起来使用。

Paul Jorgensen公式

n为存在边界值的参数个数。

  • 4n+1:基本边界测试

    每个参数取min、min+1、max、max-1各一次,其他参数取典型值;最后全部参数取典型值

  • 6n+1:健壮性边界测试

    每个参数取min、min±1、max、max±1各一次,其他参数取典型值;最后全部参数取典型值

  • 3m:条件边界测试

    每个条件取自身、±1各一次

白盒测试 / Chapter 4

白盒测试就是结构化测试。两个特点:

  • 基于代码
  • 尽可能覆盖实现的行为

概论

静态白盒测试

不执行软件,审查软件设计、体系结构和代码。

特点:

  • 可发现某些机器发现不了的错误
  • 利用不同人对代码的不同观点
  • 节约计算机资源,但以增加人工成本为代价

动态白盒测试

提供源代码和可执行程序,测试过程需要在计算机上执行程序。

优点:

  • 能检测代码中的判断和路径
  • 对代码的测试比较彻底

缺点:

  • 无法检测不可达路径
  • 不能验证需求规格

覆盖准则

我们不可能进行穷举测试,覆盖准则回答了“测试执行到何时才是足够”的问题。

基于控制流的动态白盒测试方法

语句覆盖

测试用例能使得每个可执行语句都至少执行一次。

例子:

问题:

  • 100%的语句覆盖很困难,可能存在不可达代码
  • 可能无法发现一些严重问题

判定覆盖

测试用例使得被测程序的每个判定分支至少经过一次(即真假至少取一次)。

特点:

  • 判定覆盖包含了语句覆盖,并避免了遗漏边的问题
  • 不能发现条件表达式中的错误

条件覆盖

保证每个判断中的每个原子条件的可能取值(不是每种组合)至少满足一次。

例:if A and B then Action1

则(1)A=true,B=true(2)A=false,B=false 两个用例即满足要求

条件覆盖不能保证程序所有分支都被执行。

条件组合覆盖

保证每个条件的取值组合至少出现一次。问题是代价昂贵(2^n)。

某些条件组合是不可能的(如F OR F = F)。

判定条件覆盖

每个条件的所有可能取值至少一次(条件覆盖),每个判断本身所有可能结果也至少一次(判定覆盖)。

路径覆盖

保证每条可能执行到的路径都至少经过一次。

优点:相对彻底;缺点:路径数可能指数级增加(2^n,n是分支次数);可能存在不可达路径

基本路径测试

寻找基本路径,保证每条路径至少执行一次。

  • 从流程图到流图

    流图:描述程序中的逻辑控制流(顺序结点可以合并)

  • 寻找基本路径

    基本路径:贯穿程序的、至少引入一组新的处理语句或一个新判断的程序通道

    例:

    圈复杂度:度量基本路径数,也是所有语句被执行一次所需测试用例数的下限。高圈复杂度的模块蕴含错误的可能性最大,是测试中关注的焦点。

    基本路径集合可能有多种,但基本路径数是确定的,等于圈复杂度。

    寻找基本路径

    • 找到从入口到出口的最短路径
    • 递归地改变该最短路径上所有判定结点的真假情况,生成新的路径
    • 直到找到所有基本路径
  • 产生测试用例

    根据基本路径设计测试用例进行测试。

基本路径的本质

每一条路径可以表示成边的向量,Px=(e1, ..., en)(n为边数,元素为该边在路径中的出现次数)。其他任何路径对应的向量,都可以用这些基本路径的向量线性组合得到。这说明只要基本路径测试正确,则其他逻辑也测试正确。

循环的处理

  • 简单循环

    跳过;执行一次;执行两次;执行m次;执行n-1、n、n+1次(n为循环次数,m<n)

  • 嵌套循环

    • 先测试最内层循环,此时外层的循环变量取最小值,内层按简单循环测试
    • 从内往外测试上层循环,更外层的取最小值,更内层的取典型值,该层按简单循环测试
    • 最后全体按同时取最小或最大循环次数测试
  • 串接循环

    • 串接互相独立:分别用简单循环方法测试
    • 串接不独立(第一个循环变量与第二个循环控制相关):把第一个看作外循环,第二个看作内循环,按嵌套循环测试
  • 非结构循环

    需要先进行结构化。可以使用重复编码法、状态变量法、判定转移法。

基于数据流的动态白盒测试方法

根据程序中变量定义和其后变量使用的位置来选择程序的测试路径。

一些定义:

  • P:程序

  • G(P):程序流图

  • V:变量集合

  • PATH(P):P的所有路径集合

  • DEF(v, n):变量v的定义节点是n

  • USE(v, n):变量v的使用节点是n

    • P-USE:谓词使用,即在条件判断语句中使用
    • C-USE:运算使用,即在计算表达式中使用
    • O-USE:输出使用
    • L-USE:数组定位使用
    • I-USE:循环迭代次数控制使用
  • DU-PATH:定义-使用路径,是PATH中的某条路径,以DEF起始,中间可有其他DEF,到USE终止

  • DC-PATH:定义-清除路径,DEF起始,中间没有其他DEF

测试过程

  • 分析出DEF和USE节点,记DEF节点数为NDEF,USE节点数为NUSE
  • 列出可能的DU-PATH(NDEF*NUSE条)
  • 约简DU-PATH,对于相同前缀的,只保留最长的
  • 针对每个剩下的DU-PATH设计测试用例

Q问题

面向路径的测试数据生成问题——是否存在一组输入,使得P中任意一条语句可被执行,在理论上是不可判定的。

解决方法:

  • 随机法
  • 静态法
    • 符号执行:用符号值表示程序变量,然后模拟程序执行
    • 区间算术:数值和变量都用区间表示,然后进行区间消减
  • 迭代松弛法
  • 遗传算法
  • 模拟退火

面向对象软件测试 / Chapter 5

面向对象核心概念

  • 对象(实例):可操作性的实体

  • 消息:对象之间通过消息传递来协作

  • 接口:对象行为声明的集合

  • 类:具有共性的对象的集合

  • 封装

  • 继承:类的依赖关系

  • 多态:重载,动态绑定

OO软件测试概论

与传统测试的异同

  • 单元测试时基于两个基本元素:METHOD和CLASS
  • 系统测试与传统测试类似,仍然基于需求规约
  • 集成测试是OO测试最复杂的部分

面向对象技术对软件测试的影响

  • 类的使用

    使得基本可测单元是类或对象,而不是子程序。在对每个类进行单元测试后还要对类簇进行测试。

  • 封装的使用

    信息隐藏使得对象的一部分不可访问,减轻了波动影响。但测试时经常需要访问对象的内部状态,信息隐藏给这带来了难度。

    修改时需要大量的回归测试。

  • 继承的使用

    要确定衍类中从基类继承的已测试的功能是否需要再测试。

  • 多态和动态绑定的使用

    引入了不可判定问题:难以确定该用例使得哪个多态方法被激活;多态组件的每个可能的绑定都需要独立测试,而实际上又难以找到所有的绑定。

    状态的控制分布在整个系统中,使得难以对每个状态进行单一的测试。

  • 抽象的使用

    要执行内部的结构测试时,降低了软件的可测试性。

OO软件测试

OO软件的开发过程

采用迭代式增量开发过程模型,每次迭代包含OOA(分析)、OOD(设计)、OOP(编程)三个阶段。

面向对象测试模型(OOTM)

在整个软件开发生命周期全过程中不断测试。

  • OOA Test、OOD Test

    测试分析和设计的结果,由建模专家、领域专家、软件专家参与

  • OOP Test

    针对编程风格和程序代码进行测试,采取单元测试、集成测试等手段

  • OO Unit Test

    对具体单一的功能模块的测试(类)

  • OO Integrate Test

    对系统内部的相互服务进行测试(函数间、类间合作)

  • OO System Test

    最后阶段的测试,主要以用户需求为测试标准

面向对象单元测试(OO Unit Test)

面向对象的单元测试,实际就是对类的测试。

  • 基于服务的类测试策略

    考察类中的方法对数据的操作。

    为了避免软件测试的盲目性,Kung提出了块分支图法(BBD)

    一个方法f的BBD是一个五元组(修改前的类Du, 修改后的类Dd, 参数表P, 调用的服务Fe, 控制结构图G)

    构造BBD图后可对程序的流程进行抽象进行测试:

    • 绘制服务的控制流图
    • 确定基本路径集(每个可执行语句至少一次)
    • 生成测试用例
  • 基于状态的类测试策略

    从外界向对象发送特定消息序列,来测试对象的响应状态。利用对象状态图(OSD)模型来测试:

    OSD描述了对象在其生命周期中的所有状态及其状态之间的相互转移。构造过程如下:

    • 扫描源程序,得出执行分析表
    • 确定对象状态
    • 构造状态转移
    • 构造测试消息序列
    • 生成测试用例(根据每条测试消息序列,选择相应的数据进行测试)

面向对象的集成测试(OO Integrate Test)

由于程序的控制流无法确定,只能对编译完成的程序做基于黑盒的集成测试。要参考OOD的结果。

  • 静态测试

    得出源程序的类系统图和函数功能调用关系图,检测程序结构是否符合设计要求(OOP是否符合OOD要求)

  • 动态测试

    根据静态测试得出的图表,设计测试用例,达到一定的覆盖标准

    设计测试用例的方法:

    • 确定类的状态和行为
    • 确定待测类的所有关联
    • 根据类的对象构造测试用例,使用一定的输入激发某种状态,也要设计类禁止的负例

面向对象的系统测试(OO System Test)

测试软件与系统其他部分配套运行的表现。要参考的OOA的结果。

主要测试内容:

功能测试;强度测试;性能测试;安全测试;恢复测试;可用性测试;安装/卸载测试

性能测试 / Chapter 6

引言

性能需求是一种非功能性需求。

性能测试是模拟正常、峰值、异常负载条件下,测量系统的性能指标能否达到需求,以找出瓶颈,优化系统。

性能测试的步骤

  • 熟悉应用:以知道需要模拟什么
  • 测试需求:可能需要进行指标的转换(UV如何转换成吞吐量、响应时间指标)
  • 测试准备
    • 机器数量
    • 网络环境:带宽应高于服务器吞吐量,避免出现瓶颈
    • 测试数据准备:用户注册、数据量
    • 测试用例设计
    • 测试脚本准备
  • 测试执行:监控客户端和服务器性能,后续归档处理
  • 测试结果分析:内存问题、共享资源竞争问题

性能测试的指标

  • 响应时间

    网络传输时间+应用服务器处理时间+数据库处理时间

  • 并发用户数

  • 吞吐量

    • 业务视角:请求数/秒、页面数/秒…
    • 网络视角:字节/秒
  • 资源利用率(内存、磁盘、处理器、网络)

    实际使用/总量

性能测试的方法

  • 基准测试

    制定一个性能基准测试标准。系统变化之后,进行一次相同标准的测试,即可看出变化对性能的影响

  • 负载测试

    找出负载逐渐增加时系统性能指标的变化情况,找出系统的负载极限

  • 压力测试

    找出高负载系统下的问题,如资源竞争、同步问题、内存泄漏

  • 容量测试

    找出能正常运行的最大负载或工作量

  • 失效恢复测试

    局部发生故障,能多大程度上继续使用系统

  • 并发测试

  • ……

例子 - 压力测试

相关工具:LoadRunner、QALoad…

安全测试 / Chapter 7

引论

基本概念

  • safety安全可靠:软件在运行过程中不到达某个不安全的状态
  • security安全保密:软件不会被黑客攻击
  • vulnerability漏洞:系统设计、实现或操作和管理中存在的缺陷或弱点

为什么要关注软件安全

  • 黑客攻击机会越来越多,越来越容易
  • 漏洞利用速度越来越快
  • 病毒的种类和感染的机会越来越多

软件安全问题

安全问题 例子
内存安全 缓冲区溢出问题可能导致攻击者控制内存空间,执行恶意代码
进程/线程安全 线程同步问题、线程协作问题、线程死锁问题、线程控制问题…
异常/错误处理 异常捕获安全、异常处理安全…
输入安全 不要信任用户的任何输入…
国际化安全 字符集转换安全
面向对象安全 对象的内存分配与释放、序列化安全…
Web安全 XSS攻击、SQL注入…
访问控制不当 特权提升问题…
远程调用安全 恶意调用RPC服务器中的过程…
拒绝服务攻击 DoS、DDoS…
数据加密保护 加密算法不良、密码保存不安全…
代码注入 DLL注入…

产生的原因:观念不足;软件设计不好;编码错误;测试不到位…

解决之道

先验方法

  • 让每个人都参与进来

    软件安全观念教育;同步行业安全问题

  • 主动的安全开发过程

    • 攻击面最小化:尽量减少暴露给用户的可受攻击的地方
    • 威胁建模:对最可能影响系统的威胁进行系统的识别和评估

后验方法

  • 软件安全测试

    一般测试以发现BUG为目标,安全测试以发现安全隐患为目标。

  • 渗透测试

    通过模拟恶意黑客的攻击方法,来评估计算机网络系统安全。

回归测试 / Chapter 8

在软件日常维护、迭代更新中,需要对变化的部分加以测试。回归测试就是仅对修改的部分进行测试,并且保持原有测试覆盖的方法。

引言

过程步骤

  • 提出修改需求
  • 修改软件制品(artifact)
  • 选择测试用例,执行测试
  • 识别失败结果
  • 确认错误,排除错误

策略

  • 全部重测

    优点:不用花精力选择测试用例;缺点:耗时较长,可能产生浪费

  • 有选择的重测

    优点:适合小部分的修改;缺点:需要选择测试用例

开销

  • 两种测试用例
    • T1:为了测试改变的代码的新测试用例
    • T2:原有测试用例要进行有效性重确认
  • 提高效率的实用性建议
    • 使用工具
    • 考虑依赖性(模块依赖、修改依赖)

波及效应分析(REA)

因为软件工件间的依赖性,所以需要REA来发现被影响到的部分。

波及效应分析的两种方法

  • 字符串匹配或交叉应用
  • 程序切片

波及效应的分类

  • 直接波及
  • 诱发波及

如果直接波及后不需要进一步的更改,那么诱发波及就不需要分析。

posted @ 2020-05-27 22:38  z0gSh1u  阅读(930)  评论(1编辑  收藏  举报