1.软件危机
软件工程的三个核心问题:软件开发速度、软件制品质量、软件开发成本
速度:软件的发展水平远远滞后于硬件的发展水平,生产率低下,软件制造仍然是一种人工集约生产方式
质量:软件的质量低下,不能满足用户的需求、适应性差
成本:软件开发成本居高不下
2.软件工程的发展
20世纪 60~80 年代:瀑布模型、过程化语言、支持工具
20世纪 80 年代后:软件复用技术、软件生产管理、面向对象语言
近几年:软件复用技术(构件技术、平台技术、需求工程技术、领域分析技术、应用集成技术等)
软件工程三要素: 方法、工具、过程
1.软件
软件 = 程序 + 文档
2.软件开发的本质
映射,即实现问题空间的概念和处理逻辑到解空间的概念和处理逻辑之间的映射
3.系统建模
运用所掌握的知识,通过抽象,给出该系统的一个结构 - - - - 系统模型
常用建模手段:
- 结构化方法
- 面向对象方法
- 面向数据结构方法
4.软件系统模型
概念模型:描述软件是什么
软件模型:实现概念模型的软件解决方案;包括 设计模型、实现模型、部署模型
1.定义
一个需求是有关一个“要予构造”的陈述,描述了待开发产品/系统功能上的能力、性能参数或其他性质
2.性质
- 必要的:该需求是用户所要求的
- 无歧义的:
该需求只能用一种方式解释
采用需求复审验证 - 可测的:该需求是可以进行测试的
- 可跟踪的:该需求可从一个开发阶段跟踪到另一个阶段
- 可测量的:该需求是可测量的
3.分类
- 功能需求
- 非功能需求:
1、性能需求
2、外部接口需求:用户 / 硬件 / 软件 / 通信 接口;内存约束;运行;地点需求
3、设计约束
4、质量属性
4.发现技术
- 自悟:需求人员把自己作为系统的最终用户,审视该系统并提出问题
- 交谈:需求人员询问用户需要的是一个什么样的系统
- 观察:通过观察用户如何操作系统来了解系统运行的环境
- 小组会:与客户共同开发需求
- 提炼:复审技术文档并提取相关信息
1.定义
是一个软件/产品/系统所有需求陈述的正式文档,它表达了一个软件/产品/系统的概念模型,又称 需求规格说明书
2.特性
- 重要性和稳定性程度:对需求进行分级
- 可修改的
- 完整的:没有被遗漏的需求
- 一致的:不存在互斥的需求
特定需求 是文档(需求规约)的核心
3.表达风格
- 非形式化的需求规约:用自然语言表达需求规约
- 半形式化的需求规约:用半形式化符号体系表达需求规约
- 形式化的需求规约:用基于良构数学概念的符号体系表达需求规约
基于需求规约一般还会产生两个文档:
- 初始测试计划
- 用户系统操作描述
1.分类
- 结构化分析方法
- 结构化设计方法
- 结构化程序设计方法
结构化方法中主要的描述性工具是: 数据流图、数据字典
2.数据流图(DFD图)
- 分为 变换型 和 事务性 两类
- 任何软件系统从本质上来说都是信息的变换装置
- 原则上,所有的数据流图都可以归为变换型
- 变换设计和事务设计都是结构化方法基于自顶向下,功能分解的原则提出的
3.数据字典
- 依据系统的数据流图,定义其中包含的所有数据流和数据存储的数据结构
- 直到给出构成以上数据的各项数据项的基本数据类型
- 顺序结构
+
、选择结构|
、重复结构{}
、子界m..n
4.结构化分析模型 基本术语
5.建模过程(绘制流程图的过程)
原则:自顶向下、功能分解
1)建立系统环境图
2)0层图:从0层图开始对流程图中的要素编号
3)1层图
4)… …
构建系统功能模型步骤:
1)建立系统环境图,确定系统语境
2)自顶向下,逐步求精,建立系统的层次数据流图
3)定义数据字典
4)描述加工
6.判定表
判定表也称决策表,是一个二维表,它说明了每一种条件组合所产生的结果
该表分为四个象限:
- 左上限代表所有的条件
- 左下限代表可能的结果
- 右上限代表每一种条件的取值(用Y和N来表示)
- 右下限用X表示所对应的条件组合所产生的结果
7.判定树
判定树也称决策树,是用来描述在一组不同的条件下,决策的行动是根据不同条件及其取值来选择的处理过程。业务规则的描述通常可以使用判定树这一过程描述工具
1.总体设计的目标:
- 建立系统实现所需要的软件模块
- 即系统中可标识的软件成分以及这些模块的直接调用关系
2.模块结构图:
结构图是对软件总体结构的一种图形描述,它显示了软件的层次结构、组织、通讯。
3.层次图:
使用矩形框表示一个模块,用框间的连线表示模块的调用关系
高内聚低耦合原则: 应该尽力使模块的作用域在其控制域之内
4.详细设计主要任务
给出软件模块中各个模块内部的算法设计(模块设计)
5.流程图:
6.盒图(N-S图):
一种不允许违背结构程序设计精神的图形工具
7.PAD图:
问题分析图(PAD图):是用二维树形结构的图来表示程序的控制流
8.结构化程序设计的本质
- 使程序的控制流程 线性化
- 实现程序的动态执行顺序 符合 静态书写的结构
- 从而增强程序的可读性
在软件设计期间对方法的规约使用 自然语言 或适当地使用 伪码
如果一个加工的输入数据和输出数据之间的逻辑关系比较复杂,应该用 判定表或判定树 来描述
结构化语言 是介于 形式语言 和 自然语言 之间的一种形式化语言
协作是一个交互,涉及交互的三要素是交互各方、交互方式、交互内容
1.在UML类图中表示具体类
- 具体类在类图中用矩形框表示,矩形框分为三层
- 第一层是类名;第二层是类的属性(成员变量);第三层是类的操作(方法)
- 抽象类的类名以及操作(抽象方法)的名字都用斜体字表示
- 接口在类图中的第一层顶端用构造型
<<interface>>
表示
2.成员变量以及方法前的访问修饰符用符号来表示
+
表示 public:可供其他类访问-
表示 private:只有本类可以访问#
表示 protected:子类可以访问~
表示 package:同一包中声明的类可以访问
类
抽象类
接口
包
1.实现关系
2.泛化关系
指对象与对象之间的继承关系
3.关联关系
关联关系(Association)是指对象和对象之间的连接,它使一个对象知道另一个对象的属性和方法
在Java中,关联关系的代码表现形式为一个对象含有另一个对象的引用
关联关系有单向关联和双向关联:
如果两个对象都知道(即可以调用)对方的公共属性和操作,那么二者就是双向关联
如果只有一个对象知道(即可以调用)另一个对象的公共属性和操作,那么就是单向关联
大多数关联都是单向关联,单向关联关系更容易建立和维护,有助于寻找可重用的类
在UML图中,双向关联关系用带双箭头的实线或者无箭头的实线双线表示
单向关联用一个带箭头的实线表示,箭头指向被关联的对象
一个对象可以持有其它对象的数组或者集合
在UML中,通过放置多重性(multipicity)表达式在关联线的末端来表示
多重性表达式可以是一个数字、一段范围或者是它们的组合
多重性允许的表达式示例如下:
- 数字:精确的数量
*
或者0..*
:表示0到多个0..1
:表示0或者1个,在Java中经常用一个空引用来实现1..*
:表示1到多个
4.依赖关系
依赖(Dependency)关系是一种弱关联关系
如果对象A用到对象B,但是和B的关系不是太明显的时候,就可以把这种关系看作是依赖关系
在Java中的具体代码表现形式为:
- B为A的构造器或方法中的局部变量
- 方法或构造器的参数
- 方法的返回值
- 或者A调用B的静态方法
在UML类图中,依赖关系用一个带虚线的箭头表示,由使用方指向被使用方,表示使用方对象持有被使用方对象的引用
5.聚合关系
- 聚合(Aggregation)是关联关系的一种特例,它体现的是整体与部分的拥有关系,即 “has a” 的关系
- 此时整体与部分之间是可分离的,它们可以具有各自的生命周期
- 部分可以属于多个整体对象,也可以为多个整体对象共享,所以聚合关系也常称为共享关系
- 例如,公司部门与员工的关系,一个员工可以属于多个部门,一个部门撤消了,员工可以转到其它部门
在UML图中,聚合关系用空心菱形加实线箭头表示,空心菱形在整体一方,箭头指向部分一方
6.组合关系
- 组合(Composition)也是关联关系的一种特例,它同样体现整体与部分间的包含关系,即 “contains a” 的关系
- 但此时整体与部分是不可分的,部分也不能给其它整体共享,作为整体的对象负责部分的对象的生命周期
- 这种关系比聚合更强,也称为强聚合。如果A组合B,则A需要知道B的生存周期
- 即可能A负责生成或者释放B,或者A通过某种途径知道B的生成和释放
- 例如:人包含头、躯干、四肢,它们的生命周期一致。当人出生时,头、躯干、四肢同时诞生
- 当人死亡时,作为人体组成部分的头、躯干、四肢同时死亡。
在UML图中,组合关系用实心菱形加实线箭头表示,实心菱形在整体一方,箭头指向部分一方
1.特点
以 用况驱动 、 体系结构为中心 的 迭代、增量 式开发
用况驱动 用况是能够向用户提供有价值结果的系统中的一种功能,获取的是功能需求;在系统的生存周期中,以用况作为基础,驱动系统有关人员对所要建立系统的功能需求进行交流,驱动系统分析、设计、实现和测试等活动,包括制定计划、分配任务、监控执行和进行测试等,并将它们有机地组织在一起,使各个阶段中都可以回溯到用户的实际需求
以体系结构为中心 系统体系结构:是对系统语义的概括描述,对所有项目有关人员都是可以理解的
迭代与增量 迭代是重复的部分、增量是增加的部分;一个迭代是一个完整的开发循环,产生一个可执行的产品版本,是最终产品的一个子集,它增量式地发展,从一个迭代过程到另一个迭代过程到成为最终的系统
2.核心工作流
- 六大核心过程工作流:如下
- 三大核心支持工作流:配置和变更管理、项目管理、环境
商业建模工作流 描述如何为新目标组织开发一个构想,并基于这个构想在商业用况模型和商业对象模型中定义组织的过程、角色、责任
需求工作流 描述系统应该做什么,并使开发人员和用户就这一描述达成共识;为了达到该目标,要对需要的功能和约束进行提取、组织、文档化;最重要的是理解系统所解决问题的定义和范围
分析和设计工作流 将需求转化为系统的设计,为系统开发一个健壮的结构并调整设计使其与实现环境相匹配,优化其性能;分析设计的结果是一个设计模型和一个可选的分析模型。设计模型是源代码的抽象,由设计类和一些描述组成。设计类被组织成具有良好接口的设计包和设计子系统,而描述则体现了类的对象如何协同工作实现用况的功能。设计活动以体系结构设计为中心,体系结构由若干结构视图来表达,结构视图是整个设计的抽象和简化
实现工作流 以层次化的子系统形式定义代码的组织结构;以组件的形式(源文件、二进制文件、可执行文件)实现类和对象;将开发出的组件作为单元进行测试以及集成由单个开发者所产生的结果,使其成为可执行的系统
测试工作流 验证对象间的交互作用,验证软件中所有组件的正确集成,检验所有需求已被正确的实现,识别并确认缺陷在软件部署之前被提出并处理
部署工作流 生成版本并将软件分发给最终用户,描述了:软件打包、生成软件本身以外的产品、安装软件、为用户提供帮助、计划和进行beta测试版、移植现有的软件和数据、正式验收
分类
黑盒测试:
又称功能测试,根据程序功能的分析,推演出由函数定义域中有代表性的元素组成测试集
这些数据应包括对程序是有效的和无效的输入,极端的、正常的、特殊的数据元素
因此,黑盒测试是从外界来检查模块或程序的功能,也即根据模块的输入和输出,得出所得结构的差异,无须知道内部逻辑
黑盒测试又分为:等价类法、边值分析法、因果图法、错误猜测法 等
白盒测试:
又称结构测试或逻辑覆盖法,根据对软件内部逻辑结构的分析,选取测试数据集;而测试数据集对程序逻辑的覆盖程度决定了测试完全性的程度
采用覆盖标准:语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖 等
依据的是程序内部的逻辑结构
1.控制流程图
一种表示程序控制结构的图形工具,其基本元素是节点、判定、过程块
过程块:不由判定、节点分开的一组程序语句
判定:控制流可以分叉的程序点
节点:控制流可以结合的程序点
下图即一程序流程图,其中含两个判定
其控制流程图为:
过程块:1、3、5、6、7
判定:2
节点:4
2.路径测试
该控制流程图有四条不同的路径:
L1:ace 、L2:abd 、L3:abe 、L4:acd
路径测试:执行所有可能的穿过程序的控制流程路径
对于复杂的控制流程图,基本不可能实现
3.语句测试
至少执行程序中所有语句一次,即只要设计一种能通过一条路径的测试用例,就覆盖了所有语句
语句覆盖是最弱的逻辑覆盖准则,因为即使判定的逻辑运算写错,仍有可能覆盖该语句
4.分支测试
至少执行程序每一分支一次;例如通过上述例子中的四条路径一次
分支覆盖是一种比语句覆盖稍强的逻辑覆盖,但若第二个判定的逻辑运算写错,仍有可能覆盖该分支
5.条件组合测试
至少执行每个判定中所有可能的条件取值组合一次,即在分支测试上再细分每个判定中的逻辑运算
语句覆盖<分支覆盖<条件组合覆盖<路径覆盖
依据软件行为的描述
1.事务流测试
事务:以用户的角度所见的一个工作单元
一个事务由一系列操作组成。其中某些操作可含有系统执行成分,或含有设备执行成分,它们共同写作,完成用户的一项工作
事务流图:系统行为的一种表示方法,为功能测试建立了软件动作模式,是一种数据流图
操作:1、3、5、6、7
分支:2
节点:4
2.等价类划分
等价类 输入域的一个子集,在该子集中,各个输入数据对于揭示程序中的错误都是等效的。即:以等价类中的某些代表值进行的测试,等价于对该类中其他取值的测试
有效等价类 指那些对于软件的规格说明书而言,是合理的、有意义的输入数据所构成的集合- - - - 用于实现功能和性能的测试
无效等价类 指那些对于软件的规格说明书而言,是不合理、无意义的输入数据所构成的集合- - - - 用于测试那些所实现的功能和性能不符合规格说明书的要求
等价类划分原则
如果输入条件规定了输入数据的取值范围或值的个数,则可以确定一个有效等价类和两个无效等价类
3.边界值分析
边界值分析是一种最常用的黑盒测试技术
因为测试工作经验表明,大量的错误经常发生在输入或输出范围的边界上
原则:
- (1)如果某个输入条件规定了输入值的范围,则应选择正好等于边界值的数据,以及刚刚超过边界值的数据作为测试数据
- (2)如果某个输入条件规定了值的个数,则可用最大个数、最小个数、比最大个数多1、比最小个数少1的数作为测试数据
- (3)根据规格说明的每个输出条件,使用前面的原则(1)
- (4)根据规格说明的每个输出条件,使用前面的原则(2)
- (5)如果程序的规格说明中,输入域或输出域是一个有序集合,在实践中,则经常选取集合的第一个元素、最后一个元素以及典型元素作为测试用例
- (6)如果程序中使用了内部数据结构,则应选择这个内部数据结构的边界上的值作为测试用例
- (7)分析规则说明,找出其他可能的边界条件
4.因果图
是通过从自然语言书写的功能说明表中找出 因 - - - 输入条件 和 果 - - - 输出结果
通过因果图将功能说明转换成一张判定表,然后为每种输出条件的组合设计测试用例
软件测试是按照与系统开发相反的方向来进行的。
依次为:单元测试、集成测试、有效性测试、系统测试
1.单元测试
主要采用白盒测试技术,辅以黑盒测试技术;集中于每个独立的模块,该测试以详细设计文档为指导,测试模块内的重要控制路径
步骤:
2.集成测试
集中于模块的组装,其目标是发现与接口有关的错误,将经过单元测试的模块构成一个满足设计要求的软件结构
3.有效性测试
通常采用黑盒测试技术,目标是发现软件实现的功能与需求规格说明书不一致的错误
4.系统测试
集中检验系统所有元素(包括硬件、软件)之间的协作是否合适,整个系统的性能、功能是否达到