南京大学软件学院软件测试期末复习。
选择题 10 题(源码、移动、ai)433
问答题
应用题
测试用例优先级
源码测试
- 随机测试(选择、问答为主,优势、特点、过程)
- 变异测试(与 ai 结合、变异测试的理解)
- 差分测试(基本概念)
- 通过将同一测试用例运行到一系列相似的程序来发现错误
- 蜕变测试(基本概念)
测试用例优先级
- 主要算法的流程及复杂度(贪婪算法、额外贪心的复杂度)
- APFD 计算(给公式,用 2-3 个方法,并且计算 APFD 的值)
- 算法应用
测试用例选择
- 主要方法
- 动态静态
- 与测试用例优先级的区别和联系
测试用例优先级 vs 测试用例选择
移动应用
- 基于图像理解的移动应用自动化测试
- 能够了解各个任务的难点
- 能够论述各个任务的解决方法
- 核心思想
- 方法步骤
- 基于群智协同的众包测试
- 能够了解众包的难点
- 能够了解基本的机制
- 能够了解解决方法
- 基于图像理解的移动应用自动化测试
AI 测试
- AI 测试概述
- 与传统测试的区别
- 测试的难点
- 模糊测试
- 基本流程
- 数据生成
- 效果反馈
- 简单应用
- 测试二
- 图像扩增
- 公平性
- 后门攻击
- AI 测试概述
# 源码测试
# 自动化测试
# 软件缺陷的触发和传播机理
- Software Fault: A static defect in the software (i.e., defect) 软件缺陷:软件中的静态缺陷
- Software Error: An incorrect internal state that is the manifestation of some fault 软件错误:不正确的内部状态,是某些故障的表现
- Software Failure: External, incorrect behavior with respect to the requirements or other description of the expected behavior 软件故障:相对于需求或预期行为的其他描述的外部、不正确的行为
PIE 模型理论:Execution 运行、Infection 感染、Propagation 传播
# 测试的局限性
输入空间庞大:无法穷举所有输入
实现逻辑复杂:无法想到所有场景
测试语言未知:无法判定测试的预期输出
# 随机测试
- 定义:随机生成测试数据并执行测试。
- 理论基础是大数定律,即在试验不变的条件下,重复试验多次,随机事件的频率近似于它的概率,这可以让概率低的偶然现象发生。
- 应用场景:
- 断言失败
- 异常崩溃
- 无效输入:对无效的输入过滤,便于开发者进行防御式编程
- 错误输出
# 变异测试
- 定义:是将变异体视作测试目标,利用变异分析的结果来支持、评估、引导软件测试的过程
- 目的:找出有用的测试用例,发现程序中真正的错误;可评估测试集的错误检测能力
- 变异分析:
- 变异体:基于一定的语法变换规则,通过对源程序进行程序变换得到的一系列变体
- 变异得分:对测试套件错误检测能力的量化,公式:杀死的变体占所有变体的百分比
- 变异算子:一系列语法变换规则
- 缺陷传播模型:RIPR 和 PIE
- RIPR:Reachability, Infection, Propagation Revealability
- PIE:Execution,Infection, Propagation
- 解释:
- R & E:缺陷所在的位置可以被执行到
- I:缺陷的执行影响了程序的状态
- P & PR:程序状态的影响传播到了输出
- 变异的分类(根据杀死条件不同)
- Weak mutation:变异导致紧随变化位置之后的程序状态发生了改变(R&E)
- Firm Mutation: 变异导致远离变化位置的程序状态发生了改变(I)
- Strong Mutation:变异导致程序的输出发生了变化(P&PR)
- 变异要求变高,变异体质量提升
- 变异体的分类
- 有效变异体:符合需求,可以产生模拟缺陷的变异体
- 夭折变异体:变异时遵循语法规则,但产生的变异体没有通过编译
- 冗余变异体:伴随着更强的变异体被杀死
- 等价变异体:语法不同、语义相同 (针对待测程序 P 与变异体 MUT)
- 语义相同:对于相同的输入,两个程序总能给出相同的输出
- 重复变异体:语义相同 (针对待测程序 P 的两个变异体 MUT1 和 MUT2)
- 蕴含变异体:如果杀死 M1 的用例都能杀死 M2,那么 M1 蕴含 M2(针对两个变异体 MUT1 和 MUT2)
- 等价变异体:语法不同、语义相同 (针对待测程序 P 与变异体 MUT)
- 基础假设:
- 缺陷是简单的,可模拟的:老练程序员假设
- 缺陷可叠加:复杂变异体通过耦合简单变异体得到
- 能够杀死简单变异体的测试用例可以杀死复杂变异体
- 不是一直正确,同时修改时可能相互覆盖
- 缺陷检测有效性:
- 测试用例最重要的属性:缺陷检测能力
- 传递性假设:杀死变异体的测试用例在真实世界中也有效(所以变异得分是很有用的)
- 测试过程:
- 变异体筛选 - 变异体生成 - 变异体优化 - 变异体执行 - 变异得分计算
- 变异体筛选:分两种方式
- 对变异体筛选(即变异体约减),约减策略有三:
- 随机选取:随机扔掉一些变异体,丢失率损失不多
- 基于类型:某些类型变异体更重要
- 基于分布:AST 选取更分散的变异体
- 对变异算子筛选,再生成变异体
- 好处:减少无关变异体的生成,节省开销
- 变异算子概念:是一系列程序变换规则,反映了特定的缺陷类型
- 分类:对源代码、对编译结果(中间表示)、元变异
- 对变异体筛选(即变异体约减),约减策略有三:
- 变异体生成:将变异体实例化,为每个变体构建一个单独的源文件。生成技术有三:
- 元变异:核心是程序模式(程序模板 + 部分编译,只编译变异后的代码)
- 基于字节码(中间表示):避免编译,从而减少时间开销
- 热替换
- 变异体优化:去除等价和无效变异体
- 通过静态分析,识别并移除有问题的变异体
- 变异体执行
- 变异体矩阵:用于记录执行情况,方便计算变异得分用于优化(矩阵:测试用例 * 变异体)
- 调整测试用例次序(TCP),使计算变异得分所需执行次数下降
- 优化策略:
- 改变执行顺序(TCP)
- 匹配测试用例与变异体
- 避免执行必定存活的变异体:静态分析可检测
- 限定变异体执行时间
- 变异体矩阵:用于记录执行情况,方便计算变异得分用于优化(矩阵:测试用例 * 变异体)
- 变异得分计算:
- 变异杀死的条件:确定一个变异体是否被杀死,核心是定义程序行为
- 测试预言的生成:生成更多、更好的测试语言来杀死更多变异体
- 变异体的应用:测试生成、预言生成、测试优化、debug 引导
- 总结:
# 差分测试
差分测试本质:利用相似 / 竞品软件系统进行测试
基本思想:差分测试也称差分模糊测试,是一种常用的软件测试技术,通过向一系列类似的应用程序(或同一应用程序的不同实现)提供相同的输入,根据这些相似程序执行结果是否存在差异来判定是否检测到缺陷。
# 蜕变测试
1998 年,由 Tsong Yueh Chen 提出,是一种测试用例生成的新思路
蜕变测试本质:充分利用成功测试用例;对成功测试用例表现出的必要属性的复用
基本思想:蜕变测试依据被测软件的领域知识和软件的实现方法建立蜕变关系,生成新的测试用例,通过验证蜕变关系是否被保持来决定测试是否通过。
蜕变关系 MR:多次执行目标程序时,输入与输出之间期望遵循的关系
- 确定输入输出
- 确定蜕变关系 R
- 构建待验证的蜕变关系 R'
- 构建蜕变集合
- 检查执行结果是否满足 R'
蜕变测试中的四大误解
- 误解一:所有的必要属性都是蜕变关系 蜕变关系是和待测算法的多个输入以及这些输入对应的期望输出相关的必要属性,即蜕变关系应当和多个输入实例相关
- 误解二:所有的蜕变关系都能够划分成输入端和输出端的两个子关系
- 误解三:所有的蜕变关系都是等式关系
- 误解四:蜕变测试只能应用在测试预言缺失的场景下
# 蜕变与差分
- 相同点:
- 都利用了待测程序中的必要属性;都是黑盒测试技术
- 不同点:
- 必要属性的类型不同:蜕变测试利用了单一待测程序的必要属性;差分测试则利用了多个相似待测程序间的必要属性;
- 正确性验证的准则不同:蜕变测试的正确性验证准则是可变的,由蜕变关系决定;差分测试的正确性准则是固定的,即不同相似待测程序在同一测试输入上的输出结果应该相同。
# 回归测试概述
回归测试作为一种有效的方法,可有效保证代码修改的正确性并避免代码修改对被测程序其他模块产生的副作用。在版本迭代过程中,常用的回归测试方法往往是重新执行之前已经积累的测试用例,但是这种简单的测试用例执行的策略,也导致了一些显而易见的问题。
现有用例策略:重新执行已有测试用例
回归测试 **** 问题:用例庞大、冗余、失效、缺失
- 用例庞大:由于版本迭代,测试用例数量较多,则项目实际预算不允许执行完所有测试用例。
- 用例冗余:在迭代过程中,存在多个用例的功能相似甚至相同。
- 用例失效:部分代码修改会影响到被测模块的原有外部接口或内在语义,并导致部分测试用例失效。
- 用例缺失:若代码修改生成新的测试需求,则需额外设计新的测试用例。
回归测试 **** 优化:测试用例修复、选择、扩充、约减、优先级
- 测试用例修复:识别出因相关模块的外部接口或内在语义发生变更变为失效的用例,并对其进行修复。
- 测试用例选择:通过分析代码修改,从已有测试用例中选择出所有可检测代码修改的测试用例,并确保未被选择的测试用例在修改前后程序上的执行行为保持一致。
- 测试用例扩充:在代码修改影响分析基础上,对已有测试用例集的充分性进行评估,若不充分则设计新的测试用例以确保对代码修改的充分测试。
- 测试用例约减:在满足指定测试需求覆盖前提下,识别并移除冗余测试用例来降低回归测试用例集规模。
- 测试用例优先级:当测试预算不足以执行完所有测试用例时,可以基于特定优先级准则,对测试用例进行优先级排序以优化其执行次序,旨在最大化优先级目标。
# 移动应用
# 基于图像理解的移动应用自动化测试
- 能够了解各个任务的难点
- 深度图像理解测试工具的局限性
- 能够论述各个任务的解决方法
- 核心思想、方法步骤
# GUI 测试挑战
- 环境碎片化
- 快速演化的开发平台
- 设备、平台、网络多样化
# GUI 测试必要性
- 增强测试可复用性
- 保证测试的一致性
- 提高测试效率,减少测试开销
- 实现快速的回归测试,加快测试进度
- 实现更广的测试覆盖度,提高测试可靠性,避免人为因素
真是一堆废话啊。
# 自动化测试框架
- Selenium: 一个开源的自动化测试工具,专门用于自动化网页浏览器的操作
- Appium: 一个扩展了 Selenium 的 WebDriver 协议来支持移动应用自动化的工具,允许使用 Selenium 的客户端库来编写适用于 iOS 和 Android 应用的测试脚本
# 问题
- 测试脚本的执行依赖于操作系统接口,如 Android 的 ADB
- 定位控件所需信息依赖于移动应用的 UI 层,如 Android 的 XML 布局文件
- 人工编写脚本的时间开销大
- 脚本随应用迭代的可维护性不强
# 优化
- 减少依赖,降低成本,增加可维护性
# 解决方法
# 核心思想
自动化测试网页、移动端应用
# 方法步骤
编写脚本(控件定位 + 执行操作)
# 基于图像的简单控件定位
- Sikuli:来自 MIT 的 Sikuli 通过图像匹配算法来完成对 GUI 元素的识别和定位
- Airtest:来自网易的 Airtest 连接到某个窗口或移动设备上,然后进行 GUI 测试脚本的编写
# Sikuli (类 Sikuli 工具)存在的问题
- 测试脚本的执行仍依赖于操作系统接口,如 Android 的 ADB
- 使用像素级方式定位控件的方式难以应对复杂场景,如不同分辨率的设备
- 仍面临人工编写和维护脚本的成本
# 优化
- 追求对图像更深入的理解
# 解决方案
# 核心思想
用图像匹配算法识别和定位 GUI 元素,并执行测试操作
# 方法步骤
- 捕获屏幕图像
- 编写脚本
- 图像识别
- 相似度阈值
- 执行操作
- 反馈和调整
# 深度图像理解
# 过程
- 控件匹配
- 原分辨率 - 模板匹配: 根据相似度进行筛选, 选取距离最近的作为结果
- 跨分辨率 – 特征点匹配:分别通过阈值、面积、斜率进行筛选
- 控件提取
- 设备截图、灰度转换、边缘检测、膨胀、边缘提取、轮廓矩形
- 文字识别
- 设备截屏、加载模型、区块检测、方向检测、文字识别
- 界面理解
- 空间图像提取 UIED
- 控件属性识别、页面布局刻画、场景语义分析
- 控件理解
- 控件类型判断、控件文本提取、控件意图识别、控件关系提取
# 基于深度图像理解的录制回放工具
# 问题
- 碎片化问题,加大测试难度
- 动态内容,相似控件难识别
# 特点
- 基于图像理解技术,录制和回放跨平台的测试脚本
# 基于深度图像理解的自动化探索工具
- AI 测试探索策略
- 基于强化学习和图像理解的跨平台测试技术
# 深度图像理解测试工具(侵入式)的局限性
- 无法感知异形屏幕对 UI 控件的遮挡
- 难以模拟真实场景下人的交互操作
- 仍依赖操作系统接口执行测试操作
解决方案:侵入式 -> 非侵入式
# 非侵入的 GUI 测试:机械臂 + AI
- 外置摄像头捕获屏幕,对接实现对屏幕的视觉理解
- AI 算法选择目标控件并生成测试操作
- 调度机械臂执行各种类型的测试操作
- 模拟人为交互,摆脱底层依赖
还有一些图像理解的过程和机械臂的原理在 ppt
# 基于群智协同的众包测试
# 众包的难点
# 面临的挑战(今年的)
- 任务分配
- 任务奖励
- 众测过程引导
- 测试报告质量控制
# 具体表现为(往年的)
- 竞争多、协同少
- 测试力度分布不均匀、任务完成时呈 “长尾分布”
- 测试报告数量庞大、人工审查过于耗时
- 大量报告重复、不完善
- 整理整合报告困难
# 众包的优势
- 向开发者提供多种不同软硬件平台支持的真实用户数据和操作信息
- 更充分的测试时间,更广泛的测试方法,更多样的测试环境
# 基本的机制(流程)
- 申请上传:用户将自己的应用程序上传到众测平台,并指定相应的测试任务和酬劳信息。
- 任务选择和环境设置:众测人员自由选择想要完成的任务。选择后测试人员从平台上下载应用程序进行测试。
- 提交报告:众测人员根据选择的待测应用,对测试到的缺陷提交缺陷报告
- 生成最终测试报告:平台生成最终的缺陷报告,包括:一般信息、设备信息、操作路径等。
- 报告验证:客户验证报告,并决定如何酬劳
# 解决方法
# 协作式众包测试
完成测试任务过程中进行信息共享与任务分配,用户在本系统中既承担测试任务也承担审核任务,充分利用用户协作,完成目标任务。
- 信息共享:用户在提交报告时进行实时相似报告推荐,避免重复报告。
- 任务分配:审核页面推荐待审核的报告列表,测试页面推荐待测页面
- 协作方式:可以点赞点踩,利用用户的交叉审核,验证报告有效性。
- 一键 Fork:Fork 他人结果后进行修改,利用多人协作提升报告质量
# 众测报告聚合
目的:解决报告重复、报告无法搜索的问题。
- Aggregator:对所有的测试报告做聚类,将相同的或相似的测试报告聚为同类。
- Summarizer:对每一类测试报告做整合,将其中的相关信息以可视化的方式最大化的呈现给开发者。
Aggregator 过程:
- 距离矩阵计算
- 截屏集合的距离矩阵 DS distance of screen
- 文本集合的距离矩阵 DT distance of text
- 距离矩阵的合并
- 文本相同,0
- 截屏相同,加权
- 都不同,调和平均
- 合成层次聚类
Summarize 过程:
- 识别主报告 - pagerank 算法
- 生成补充信息 - 识别提纯,补充信息、同源信息
- 生成总结
# 众测报告排序
众测报告的优势:向开发者提供多种不同软硬件平台支持的真实用户数据和操作信息
众测报告质量管控问题:测试报告数量庞大、人工审查过于耗时
普通测试报告的排序:文本描述或程序代码的执行树
针对移动应用测试报告的排序:将截图和文本纳入考虑。
- 使用文本 + 图片结合分析的方法
报告排序原则:尽可能地发现有缺陷的报告,提高报告的审查效率
- 通过自然语言处理算法计算文本的相似度
- 关键词、文本距离
- Jaccard 距离计算
- 通过 SPM 算法(Spatial Pyramid Matching)识别缺陷截图相似度
- 特征直方图
- 截图之间的距离
- 设置阈值 y,筛选内容相同图片
- 截图集合之间的距离
- 通过使用一种多目标的优化算法结合文本与截图相似度完成针对测试报告的相似度比较
- 计算距离,公式同聚合
# 深度众测报告排序
解决主要分析文本、截图为辅、文本截图简单拼接的问题(传统众测报告排序的问题)。
过程:特征提取 -> 特征聚合 -> 相似度计算 -> 报告排序
- 图片特征提取:CV 技术提取控件 - 问题控件、上下文控件
- 文本特征提取:NLP 技术处理文本 - 缺陷描述、复现步骤
- 将所有特征聚合为两种特征类型:
- Bug Feature(BFT):与缺陷直接相关,包括问题控件和缺陷描述
- Context Feature(CFT):为缺陷构建上下文,包括上下文控件和复现步骤
- 相似度计算 deepsimilarity
- 报告排序:
- 分为两个报告池:未排序报告池、已排序报告池
- 初始化:所有报告 -> 未排序报告池;Null Report-> 已排序报告
- 从未排序报告池中,找出一份和已排序报告池中最不相似的报告加入已排序报告池,循环调用
# 众测报告半监督聚类
存在问题:
传统聚类方式的缺陷与不足
- 未利用报告语义信息
- 忽略图像文本关联
过程:
- 特征提取(应用截图 + 文本描述)
- 特征距离计算
- 利用图文语义绑定
- 距离从小到大,将 index 与各类簇进行适配
# 众测报告一致性检测 (文本和截图的一致性)
存在问题:
- 众测工人能力与专业性参差不齐,众测报告质量参差不齐
- 众测报告质量的底线:截图与文本的一致性
解决方案:
二阶段方法 - 先分类后检测
- 一阶段:根据错误特征将基于文本描述的报告分类为不同类别
- 二阶段:深入分析应用截图的 GUI 图像特征,然后应用不同的策略来处理不同类型的 Bug,以检测众包测试报告的一致性
# AI 测试
# 与传统测试的区别
- 决策逻辑上:
- 传统软件的决策逻辑:程序代码控制
- 智能软件的决策逻辑:使用深度学习模型的结构;训练后得到的权重节点
- 程序特征上:
- 传统软件:控制流和数据流构建的业务处理
- 智能软件:数据驱动构建的参数化数值计算;
- 缺陷特征:
- 传统软件系统:给定输入,比较输出,若不相符,存在缺陷
- 智能软件系统:往往不是显式的代码或参数错误
- 智能软件测试有领域性,而传统测试没有
# AI 测试的难点
- 数据量不够
- 低质量数据
- 脱离现实数据
- 脱离目标数据
- 数据分布不均
- 不充分测试(指面对恶意供给和随机数据)
# 图像扩增
- 数据扩增:通过轻微变换现有数据或创建新的合成图像来得到新数据的技术。应用领域有图像扩增、文本扩增、雷达扩增……
- 数据扩增的原因:
- 领域数据紧缺
- 数据标注困难
- 数据分布挑战
- 隐藏信息干扰:要考虑隐含条件 (人口基数等)
- 扩增方式:(这里特指 PPT 给的变异方式)
- brightness 亮度
- contrast 对比度
- pixel noise 加噪
- blurring 模糊
- translation
- scaling 缩放
- horizontal shearing 错切
- rotation 旋转
# 公平性
- 定义:鲁棒性边界因为数据集歧视(隐含条件的缺失)变得不公平
- 修正:用各类方法修正数据,如改变字段(使用 01 表示性别字段)/ 人种(使用 PS 实现风格迁移)
# 后门攻击
- 定义:根据潜在的失效点设计训练集,故意加入错误或误导性的信息,产生错误输出(训练集投毒)
- 如何注入:
- 数据投毒:训练集投毒,为一些图片添加触发器并更改标签
- 训练神经网络,观察能否发现后门
# 大题
# 测试用例优先级 TCP(Test Case Prioritization)
# 主要算法流程和复杂度
# 基于贪心的 TCP(Test Case Prioritization)
- 定义:通过设定特定优先级准则(执行时间,代码覆盖等),对测试用例进行优先级排序以优化其执行次序,旨在最大化优先级目标,例如最大化测试用例集的早期缺陷检测速率。
- 全局贪心策略
- 每轮优先挑选覆盖最多代码单元的测试用例。
- 多个用例相同随机选择。
- 增量贪心策略
- 每轮优先挑选覆盖最多,且未被已选择用例覆盖代码单元的测试用例。
- 所有代码单元均已被覆盖则重置排序过程
- 多个用例相同随机选择
- 特殊点:所有语句均被覆盖时要重置数组(但此时测过的不用再测)
- 假设有 n 个测试用例以及 m 个代码单元
- 共需排序 n 轮,每轮选择一个测试用例
- 时间复杂度
- 假设有 n 个测试用例以及 m 个代码单元,共需排序 n 轮,每轮选择一个测试用例,第 k 轮时,存在 n-k+1 个待排序用例,每个用例需与 m 个代码单元计算情况,那么时间复杂度为 O(n^2*m)
- 改进 1:计算各个单元错误检测概率 + 计算各个用例加权覆盖评估值
- 改进 2:因为覆盖了不一定安全 -> 优先选择让覆盖少的语句执行的测试用例
- 前两轮用增量贪心选 t1/t2,得覆盖数组 cc
- 后面假设选择 ti,比较产生的有序覆盖数组,选字典排序最大的(从左往右比)
- 改进 3:给重要语句加权重
# 基于相似性的 TCP 策略
- 因为故障通常聚在一起,所以让测试用例更均匀分布
- 如何计算测试用例之间的距离和测试集之间的距离?自适应随机策略!
- 自适应随机策略
- 基本定义:每轮优先与已选择测试用例集差异性最大的测试用例。让测试用例均匀地分布在输入域中。
- 执行步骤:
- 测试用例之间的距离计算
- Minimum
- Average
- Maximum
- 测试用例之间的距离计算
# 基于搜索的 TCP 策略
- 基本定义:探索用例优先级排序组合的状态空间,以此找到检测错误更快的用例序列
- 执行步骤:
- 初始种群构造:生成 N 个测试用例序列,解的编码形式为优先级排序的测试用例编号位置。如初始时对 6 个测试用例构造 2 个个体
- 交叉操作:使用单点交叉的方式。随机生成切割垫,互相交换两个用例序列切割点后部分的片段,仅交换相同测试用例的部分。
- 变异操作:对种群中的个体进行基因值的改变操作。以一定概率选择测试用例,并随机生成两个测试用例位置,进行互换,产生新的测试用例序列。如示例对个体 1 进行变异算子生成新的个体。
- 适应度评估:以语句覆盖为例,给定程序包含 m 个语句 M={s1,s2,...,sm} 和 n 个测试用例 T={t1,t2,...,tn},T' 为某一次搜索中 T 的一个优先级序列,TSi 为该测试用例序列 T' 中第一个覆盖语句 si 的测试用例下标,那么其适应度计算为:
# 基于机器学习的 TCP 策略
- 基本定义:对测试用例特征进行学习,根据预测的缺陷检测概率进行优先级排序
- 排序步骤:
- 特征提取:设计并提取测试程序中源码特征
- 存在特征:是否存在的特征(如表达式、变量特征)
- 使用特征:被使用的特征(如获取变量地址的次数)
- 缺陷模型生成:建立模型预测测试程序检测缺陷的概率
- 提供标签,是否故障
- 使用信息增益比筛选无用特征
- 使用 minmax 正则化特征
- 使用 SMO 算法训练模型,预测每个测试程序检测到缺陷的概率
- 开销模型生成:建立模型预测测试程序的运行时间
- 标签,运行时间
- 使用信息增益比筛选无用特征
- 使用 minmax 正则化特征
- 使用高斯过程训练模型,预测每个测试程序运行的时间
- 测试优先级:基于单位时间内检测缺陷能力进行优先级排序
# APFD 计算
# APFD
- 指标:平均故障检测百分比(Average Percentage of Faults Detected, APFD)
- 说明:当给定测试用例的执行次序时,该评测指标可以给出测试用例执行过程中检测到缺陷的平均累计比例
- 特点:其取值范围介于 0~100% 之间,取值越高,则缺陷检测速度越快
# APFDc
- 开销感知平均故障检测百分比(cost-cognizant average percentage of aults detected APFDc)
# NAPFD
- 归一化平均故障检测百分比(Normalized Average Percentage of Faults Detected, NAPFD)
- 特点:考虑了实际优先级排序场景中
- 测试用例集不能检测到所有缺陷
- 由于资源限制,无法执行所有测试用例
# 算法应用
# 测试用例选择 TCS Test Case Selection
- 定义:旨在从已有测试用例集中选择出所有可检测代码修改的测试用例。(即选择执行到变更部分的用例)
- 适用场景:适用于因测试预算不足以致不能执行完所有测试用例的测试场景。
# 基于程序分析的测试用例选择
简介
- 根据技术的基本定义以及程序分析技术的特点,该技术一般被认为是一种安全测试用例选择技术
- 通过程序分析技术计算出测试代码(方法、用例或套件)与生产代码之间的依赖关系,并在代码发生变更时,利用这些依赖关系将所有受到变更影响的测试代码自动选取出来,组成回归测试集。
- 测试依赖:测试代码运行到某些生产代码而产生的联系
# 依赖分析
看不同测试用例的函数依赖
# 方法
# 最小化测试用例选择
- 选出最小的子集 Tmin,Tmin 能够覆盖被测程序 P 中所有本次修改的、或者受本次修改影响的部分
- 每⼀条新增的或者被修改的语句都能够被至少⼀个来自原测试套件 T 的测试用例执行
# 安全测试用例选择技术
- 目标:选出源测试套件 T 中能够暴露修改后被测程序 P' 中的一个或多个缺陷的所有测试用例,构成安全回归测试集 Ts
- 要求:Ts 中的每个测试都能够满足以下条件之一:执行至少⼀条在 P' 中被删除的语句;执行至少⼀条在 P‘中新增的语句
# 基于数据流和覆盖的测试用例选择
- 变更后的代码 P' 中使数据交互变化的语句构成语句集合 Si,选出所有覆盖到 Si 中某条语句的测试用例,组成测试集 Td
- Td 中的每个测试都能够满足以下条件之一:执行至少⼀个在 P’中被删除的 Define-Use 对;执行至少⼀个在 P‘中新增的 Define-Use 对
# 特质 / 随机测试用例选择
- 随机测试用例选择:随机选出 m 个测试用例
- 面向剖面测试用例选择:选出与某个剖面有关的测试用例
# 动态静态
# 静态程序分析
- 定义:指在没有实际执行程序的情况下对计算机软件程序进行自动化分析的技术。
- 分析材料:源代码(大多数情况),目标语言代码(少部分,如 java 字节码)
# 动态程序分析
- 定义:通过在真实或虚拟处理器上执行程序来完成对程序行为的分析。
- 限制:使用足够的测试输入来执行目标程序,以覆盖程序所有输出
- 注意:进行动态分析时一般需要注意最小化插桩对目标程序的影响。
# 动态 V.S. 静态
总体上,动态测试选择 > 静态测试选择
- 动态分析更容易获得更丰富 (运行时信息) 程序依赖信息,测试选择更精准、安全;静态分析开销更大,且存在过拟合现象;
- 静态分析在运行测试阶段表现更好:静态分析不需要对代码进行插桩,在执行代码前就能获得测试选择所需要的测试依赖;
特征 | 动态 | 静态 |
---|---|---|
总体 | 好 | |
(运行时)程序依赖信息 | 更丰富 | |
开销 | 小 | 大 |
过拟合 | 不存在 | 存在 |
插桩 | 需要 | 不需要 |
运行测试阶段 | 表现更好 | |
优点 | 测试用例选择更加精准、安全 | 在执行代码前就能够获得测试用例选择所需的测试依赖 |
# 粒度
按照选取粒度的不同,基于程序分析的测试选择技术可划分为【基本块级、方法块级】、【文件级和模块级】。
# 细粒度
- 基本块(Basic Block,BB)级:利用 BB 级变更和 BB 级测试依赖进行测试选取
- 方法级:利用方法级变更和方法级测试依赖进行测试选取
# 粗粒度
- 文件(类)级:利用文件级变更和文件级测试依赖进行测试选取。由于 Java 语言会将每一类编译成一个.class 文件,因此针对 Java 语言的文件级测试用例选择等同于类级别测试用例选择
- 项目(模块)级:利用项目级变更和项目间依赖进行测试选取
目前类级最好使用
研究表明优势细粒度的程序分析会因为过于 “精准” 而漏选某些能够暴露缺陷的测试
# 流程
- A Phase – 分析阶段:分析代码变更、计算测试依赖
- E Phase – 执行阶段:运行选中测试
- C Phase – 收集阶段:收集测试信息。按照产生的时间点不同,信息可以分成两类:运行时信息(动态测试依赖、覆盖信息)和测试运行结果(测试运行结果、测试运行时间)
- 三阶段(Offline Mode):A -> E -> C,执行测试和收集信息分开进行。测试需要运行两遍,但是能够更早得到测试反馈
- 两阶段(Online Mode):A -> EC,在执行测试的同时收集信息。延长了测试执行时间,但总时间更短
# 类防火墙算法
- 使用对象关系图(Object Relation Graph)来描述测试类和生产类之间关系的算法。对象关系图描绘了面向对象程序中存在的继承、聚合以及关联关系。
- A 继承 B(A 是 B 的子类),则 B 改动,A 也要重新测试。
- A 聚合 B(A 是 B 的聚合类),则 B 改动,A 也要重新测试。
- A 访问 B 的数据成员 或者 A 要向 B 传递信息,则 B 改动,A 也要重新测试。此外,A 和 B 要重新集成。
# 测试用例优先级 vs. 测试用例选择
- 优先级技术是对测试用例集进行排序,以最快的速度找到缺陷,提高测试用例集的故障检测率
- 选择技术是取测试用例集的子集,能覆盖修改过的代码,降低回归测试的开销并最大化缺陷探测能力
# 模糊测试
定义:通过向目标程序提供非预期的输入并监视异常结果来发现软件漏洞的方法
# 基本流程
** 基本流程 :** 选择种子 —— 数据生成 —— 执行测试 —— 结果分析 —— 结果反馈
# 数据生成
- 种子集准备 **:** 初始种子 -> 预处理 -> 种子打包形成语料集 -> 语料集筛选规则
- 过程引导
- 种子采样:根据模糊测试变异方法从送入过程引导的语料集中形成符合变异方法输入的种子元组。
- 能量分配:旨在通过对语料集进行变异成功率检测实现在同样的测试计算资源尽可能生成多的能够成功变异的测试数据。
- 数据变异:根据所选用的变异方法,对选取的原始测试数据施加扰动,生成新的测试输入。
- 健康测试:根据所测试的程序制定了一定的规则用来检测模糊测试变异的测试数据是否有效。
- 文本数据生成
- 基于生成:根据文本生成规则和模板
- 基于变异:根据变异规则扩增
- 加噪:在原数据的基础上通过替换词、删除词等方式创造和原数据相类似的新数据。
- 回译:将原有数据翻译为其他语言再翻译回原语言,由于语言逻辑顺序等的不同,回译的方法也往往能够得到和原数据差别较大的新数据。
- 图像数据生成
- 基于生成:定义生成的规则或模板,如图像大小、像素范围、通道数
- 基于变异:维持语义的前提下进行图像变换,如(水平 | 垂直)翻转、旋转、缩放(放大 | 缩小)、裁剪、平移、高斯噪声
# 效果反馈
- 结果比对:结果参照物对比、是否产生运行崩溃
- 结果分析:覆盖率分析、传统反馈
- 模糊测试检测内容:无效输入、断言失败、错误输出、异常崩溃
- 优先级排序:模糊测试一般以测试覆盖率划分语料集优先级
- 提高测试覆盖率 - 新的种子
- 更易变异、被选取次数较少 - 更高的优先级
# 简单应用
- AI 模糊测试
- 机器翻译、自动驾驶、医疗影像
# 怎么答题
参考课上的例子
- 定义输入输出
- 种子调度
- 种子优先级排序
- 能量分配
- 测试生成
- 基于生成、基于变异
- 执行测试
- 输出分析
- 结果对比
- 结果分析
- 模糊测试检测内容
- 优先级排序
- 结果反馈