Lecture11 结构测试——数据流覆盖 Dataflow Coverage

简介

1.数据流测试集中于变量被接收的节点和这些变量值被使用或引用的节点
2.使用所有可能的数据流来验证程序的正确性,即测试定义变量中的值及其子序列使用的每个路径的执行情况
3.DU(Definition/Use)对:指的是从变量的定义到后续的使用中的每个可能的路径
4.目标是在代码中实现DU对的完全覆盖

数据流异常 Dataflow Anomalies

早期的数据流分析侧重于与变量(参数、局部变量和属性)相关的一组故障,称为数据流异常或定义/引用异常
它们包括:
1.已定义但从未使用或引用的变量
2.在使用之前被多次定义的变量

大多数现代集成开发环境,例如Eclipse 和Netbeans,都可以检测到此类问题。

数据的定义和使用

在以下情况,我们认为变量被定义:
1.它是一个Input参数,比如 public void test(String str){...}
2.在赋值语句左侧的变量 int num = 10 ;
3.它充当输出参数

在以下情况,我们认为参数被使用:
1.它充当函数被调用时的输入参数result = sum(a,b) 以及return number;
2.它在赋值语句的右侧 number = a+1,这里的a
3.谓词的一部分 if(number > 0){...}

如果在谓词predicate中使用变量,则称为谓词使用(p-use);所有其他用途都称为计算使用(c-use)

Definition-Clear Paths

Definition-Clear Paths 指的是一个变量x在定义和使用之间的路径,而这条路径的中间并没有再次定义x

Definition-Use Pair

指的是对于变量x,这里有一个关于x的定义d(x),并且有着对应的使用x u(x)。在这种情况下,d(x)和u(x)之前至少存在这一个Definition-Clear Paths

执行

1.构建 DU对 的表
确定软件测试的所有变量
识别与变量相关的所有使用
列出定义的编号和使用定义/使用表

注意:
1.变量声明不能被视为定义
2.递增和递减操作会导致在定义后立即出现使用

2.识别DU对 Identify DU-Pairs

3.编写测试用例
每个可能的DU对都是测试用例
有些DU-Pairs是不可能执行的。这些DU-Pairs被视为候选DU对,而不用为它们分配测试用例

4.Test Data
1.选择测试数据以确保每个DU对都已执行
2.测试数据选择要求测试工程师查看源代码,并选择可以让从每个定义到每个设置对象的路径都会被执行的输入参数值
3.预期输出来自于规范
4.最简单的办法是,最开始先任意组合输入input,跟着路径执行,然后列出所有覆盖的DU组合,直到所有的测试用例被覆盖

(这部分的操作实例比较复杂,建议直接看PDF)

小结

1.DU-Pairtesting 提供对所有 Definition-Usepathsina 程序的全面测试
2.它是一种强大的测试形式,即它以程序中对数据进行操作的模式生成测试数据
3.

4.对于引用对象或指针变量,很难确定引用了哪些变量
5.对于数组,很难确定数组中的哪个元素被引用(解决方案是将整个阵列视为一个变量)

结构测试小结

Lecture12 突变测试 MutationTesting

概念与简介

突变测试的概念与1970s首次被提出
在突变测试中,错误被故意引入到程序中
(通过创建程序的多个版本,每个版本都包含一个错误)
有缺陷的程序被称为原始程序的变种 mutants
突变体是通过对原始程序系统地应用突变操作 mutation operators 而产生的
(比如将原始的 if x < 1 改为 if x = 1)

突变操作 Mutation Operators

一个突变操作被认为是一个从测试的软件中得到突变体的规则
突变操作的设计是为了防止那些程序员通常会放的错误
其取决于编程语言的特性

突变测试的流程

1.为在测试中的程序构造突变体
-对原程序的每一个不同的修改作为一个突变体版本
-每个突变体只包含一个错误

2.生成测试用例和测试数据
-目前还没有一个公认的合适的方法来系统地生成测试数据
-其中有一种办法是,从查看会导致突变算子被触发的变量开始

3.将测试数据反馈给原始数据
-如果输出不正确,则修复程序并重新启动进程
-如果输出是正确的,则继续进行下一步

4.对于每一个突变体都进行测试数据

5.将每个突变体的输出与原始程序的输出进行比较
-如果输出是不同的,那么则代表突变体被测试数据”杀死”了
-如果它们是相同的,那么我们认为它们在功能上等同原始程序

6.目标是在执行了所有测试用例之后杀死所有的突变体

7.实际上,有许多自动测试的工具

突变分数

1.使用突变评分来衡量突变测试的有效性
2.一组测试数据的突变分数是该数据杀死的非等值突变体的百分比
-在这个例子中,总共有 9 个突变体,1 个等效的突变体和 8 个突变体被杀死
-给定测试数据的突变分数是8/9 = 0.89
3.如果其突变分数为100%,则该数据集被认为是充分的突变

识别故障目标 Identifying Fault Targets

1.简单的故障目标主要基于潜在的输入错误
-往往被称为一个语句级突变
2.在更高级别,算法和软件接口是合适的目标
3.在面向对象的程序中,类的关系和类的相互作用是潜在的目标
-往往被称为一个类级突变

小结

Lecture13 面向对象的单元测试软件 Unit Testing Object-Oriented Software

面向对象的测试模型

面向对象软件的特点

面向对象的设计是以类、继承和消息的概念为中心的
-类提供了一种打包数据(属性)和相关操作(方法)的机制
-继承为代码重用和共享公共功能提供了一种机制
-消息(方法调用)提供对象的外部接口

面向对象的设计特征为测试带来了额外的复杂性

测试面向对象软件的注意事项

-类:对象保留状态;状态控制通常分布在整个程序中。状态控制错误很可能发生
-继承:动态绑定和复杂的继承结构容易出错
-信息:面向对象的程序通常有很多小的组件,因此有更多的接口。接口错误更容易发生

面向对象的测试模型

面向对象软件的测试可以通过五个测试模型进行:
1.传统的
-使用接受他们所有输入的方法作为方法的参数并返回结果

2.组合的
-确保类在不同的输入组合,以不同的方法,下能正常工作

3.状态机
-所有具有属性的类都是独立的;我们的目标是实现全面覆盖,如状态转换

4.规格与设计
-根据设计规范和设计规范,使用统一建模语言(UML)图进行设计表达

5.内置测试
使用语言构建机制,比如Java中的Assertion

小结

所有常规的功能和结构技术都可以应用于类环境中的测试方法
-等价类测试、边界值分析测试、组合测试、随机测试、错误猜测
-语句覆盖、分支覆盖、决策覆盖、条件覆盖、路径覆盖和DU-Paris分析

测试用例将相同;关键区别在于测试数据

面向对象的设计特性必须格外小心:封装、继承、多态和消息序列和状态

Lecture14 软件过程中的测试 Testing in the Software Process

软件测试方法 Software Testing Approaches

1.The “BigBang” development
等待代码编写完成并测试完成的产品一次
测试活动不会阻碍完成产品的进度

这是一个冒险的策略
-产品运行的可能性可能很低,这取决于程序的大小和复杂性
-更难确定问题的根源

2.The ”Incremental” development
-测试单个模块或软件功能并编写它们
-新模块或功能以更好的质量构建在代码之上

渐进式测试的步骤 The Stages of Incremental Testing

软件开发生命周期

软件开发生命周期是组织软件产品开发的结构化计划,也称为软件过程模型
软件过程模型描述了软件开发过程中发生的各种任务或活动的方法
随着软件项目的日益复杂化,这是必需的
非结构化方法将导致成本超支、延迟交付和质量不确定
结构化的方法使软件开发过程具有可重复性和可预测性,从而提高生产效率和质量
所有结构化方法(软件过程模型)都包括作为过程一部分的软件测试,但重点不同

瀑布模型

V模型

渐进式和敏捷开发

敏捷软件开发的重点是在短时间内构建可发布的软件,通常以周为单位

它与敏捷宣言有关
-个人和交互高于处理和工具
-工作软件高于综合文档
-客户合作优于合同谈判
-响应变化而不是遵循计划

专业开发人员的需求发生了变化,这使得测试工程师的工作更加艰巨

渐进式模型

极限开发 XP

强调代码审查、持续集成、自动化测试、短文、实时沟通和团队合作
程序员负责测试他们自己的工作;测试工程师专注于帮助客户选择和编写功能测试,而不是定期运行测试

主要特点:
-沟通:与客户和程序员沟通
-简单:保持他们的设计简单和干净
-反馈:从一开始就通过软件测试获得反馈
-勇气:尽早将系统交付给客户,并建议进行补充更改

Scrum

Scrum 流程
Scrum是一种管理复杂软件项目的方法,也是Agiles软件开发的一种技巧
Scrum 从产品待办列表开始,它是产品需求的优先列表
-最有可能产生商业价值的项目位于顶部;列表分为建议的发布。
备忘录的内容来自于对项目结果感兴趣的每一个人
Scrum 团队在他们认为可以在几周内(通常是 30 天的迭代)内转化为产品功能增量的尽可能多的产品积压。这称为 Sprint
团队保持着一份在每个阶段要执行的任务清单,这被称为 “阶段性积压”
Sprint 的结果是一个可发布的工作软件。一个项目通常会有多个 Sprint

DevOps

DevOps指的是开发和运维的结合
DevOpsto 软件开发的主要驱动因素是:
-减少需求变更
-以测试和质量保证为重点
-以实现更快的交付周期
DevOps 尽可能依赖自动化工具

与过程相关的质量标准和模型