软件工程是:
(1)将系统化的、规范化、可量化的方法应用于软件的开发、运行和维护,即将工程化方法应用于软件。
(2)在(1)中所述方法的研究
1.软件是设计开发的,而不是传统意义上生产制造的。
2.软件不会“磨损”
3.大多数软件根据实际的顾客需求定制的。
软件必须适应新的计算环境或技术的需要。
必须增强软件来实现新的业务需求。
软件必须扩展到与其他更现代的系统或数据库进行互操作。
必须重新构建软件,使其在网络环境中可行。
软件过程:软件过程是工作产品构建时所执行的一系列活动、动作和任务的集合。
适用于所有软件项目,无论其规模和复杂程度如何
1.沟通(Communication): 目的是理解利益相关者的项目目标,并收集需求以定义软件特性和功能。
2.策划(Planning): 定义和描述了软件工程工作,包括需要执行的技术任务、可能的风险、资源需求、工作产品和工作进度计划。
3.建模(Modeling): 利用模型更好地理解软件需求并完成符合这些需求的软件设计。
4.构建(Construction): 它包括编码和测试以发现编码中的错误。
5.部署(Deployment): 软件交付到用户,用户对其进行评测并给出反馈意见。
普适性活动贯穿软件项目始终。
1.软件项目跟踪和控制:项目根据计划评估项目进度,并且采取必要的措施保证项目按进度计划进行。
2.风险管理:对可能影响项目成果或者产品质量的风险进行评估。
3.软件质量保证:确定和执行软件质量保证的活动
4.技术评估:评估软件工程产品、尽量在错误传播到下一个活动之前,发现并清除错误。
5.测量:定义和收集过程、项目和产品的度量,以帮助团队在发布软件的时候满足利益相关者要求。同时,测量还可以与其他框架活动和普适性活动配合使用。
6.软件配置管理:在整个软件工程中,管理变更所带来的影响。
7.可复用管理:定义产品复用的标准,并且建立构建复用机制。
8.工作产品的准备和生产:包括了生产产品所必需的活动。
任务集定义了为达到一个软件工程动作的目标所需要完成的工作。
比如需求获取就是发生在沟通活动中的一个重要的动作,其对应的任务集可能包括:
对于一个小型、相对简单的项目而言:
惯用过程模型是为了改变软件开发的混乱状态,促使软件开发更加有序。
又被称为经典生命周期(classic life cycle),它提出了一个系统的、顺序的软件开发方法。
优点:
有利于大型软件开发过程中人员的组织、管理,从而提高了大型软件项目开发的质量和效率。
当需求确定、工作采用线性的方式完成的时候瀑布模型是一个很有用的过程模型。
缺点:
过于理想,缺乏灵活性,容易产生需求偏差。
实际的项目很少遵守瀑布模型提出的顺序。
客户通常很难清楚的描述所有的需求。
客户必须要有耐心,因为只有在项目接近尾声的时候,他们才能得到可以执行的程序。
适用范围: 需求确定,工作能够采用线性的方式完成的软件。
描述了质量保证动作同沟通、建模相关动作以及早期构建相关的动作之间的关系。
V模型强调软件开发的协作和速度,将软件实现和验证有机地结合起来,在保证较高的软件质量情况下缩短开发周期。
优点:适合工程量小、人力资源少并且开发过程中改动不大的项目
缺点:错误发现时间迟,产生的风险代价高
增量过程模型侧重于每一个增量都提交一个可以运行的产品。
优点:
适用范围:
(1)进行已有产品升级或新版本开发,增量模型是非常适合的;
(2)对完成期限严格要求的产品,可以使用增量模型;
(3)对所开发的领域比较熟悉而且已有原型系统,增量模型也是非常适合的。
(4)项目在既定的商业要求期限之前不可能找到足够的开发人员
演化模型是迭代的过程模型。
原型开发(prototyping ):当需求很模糊的时候,原型开发可以帮助软件开发人员和利益相关者更好地理解究竟需要做什么。
优点:
开发者与用户充分交流,可以澄清模糊需求,需求定义比其他模型好得多
开发过程与用户培训过程同步
为用户需求的改变提供了充分的余地
开发风险低,产品柔性好
开发费用低,时间短
系统易维护,对用户更友好
缺点:
1、 没有考虑软件的整体质量和长期的可维护性。
2、 大部分情况是不合适的操作算法被采用目的为了演示功能,不合适的开发工具被采用仅仅为了它的方便,还有不合适的操作系统被选择等等。
3、 由于达不到质量要求产品可能被抛弃,而采用新的模型重新设计。
适用范围:
尽管原型可以用作独立的流程模型,但它更常用作一种可以在任何流模型的上下文中实现的技术。
统一过程模型
统一过程模型是一种“用例驱动、以体系结构为核心、迭代及增量”的软件 过程框架,由 UML 方法和工具支持。它是一种增量模型,定义了五个阶段:
a、起始阶段,包括用户沟通和计划活动,强调定义和细化用例
b、细化阶段,包括用户沟通和建模活动,重点是创建分析和设计模型。
c、构件阶段,细化模型设计,并将设计模型转化为软件构件实现
d、转化阶段,将软件从开发人员传递给最终用户,并由用户完成 beta 测试和验收测试
e、生产阶段,持续地监控软件的运行,并提供技术支持。
优点:
1.任何功能开发后就进入测试过程,及早进行验证
2.早期风险识别,采取预防措施
缺点:
敏捷宣言(Agile development manifesto):
个人和他们之间的交流胜过了开发过程和工具
可运行的软件胜过了宽泛的文档
客户合作胜过了合同谈判
对变更的良好响应胜过了按部就班地遵循计划
极限编程(Extreme Programming (XP))
极限编程是敏捷软件开发使用最广泛的一个方法。
1.策划:
开始创造“用户故事”
敏捷团队评估每个故事并分配一个成本(开发周数)
故事被分组到一个可交付增量
承诺在交付日期进行
在第一次递增之后,“项目速度”用于帮助估计后续发行版本的发布日期和进度安排,确定是否对整个开发项目中的所有故事有过分承诺。
2.设计
遵循KIS(保持简洁)原则
鼓励使用CRC(类-责任-协作者)卡(见第8章)
对于困难的设计问题,建议创建“尖峰解决方案” - 一个设计原型
鼓励“重构”: 重构是以不改变代码外部行为而改进其内部结构的方式来修改软件系统的过程。
3.编码
在编码开始之前,建议对故事进行单元测试
鼓励“结队编程”
连续集成
有助于避免兼容性和接口问题,建立能及早发现错误的“冒烟测试”
4.测试
所有的单元测试每天都执行
“验收测试”,由客户规定技术条件,并且着眼于客户可见的、可评审的系统级的特征和功能。
待定项(backlog)——一个能为用户提供商业价值的项目需求或特性的优先級列表。待定项中可以随时加入新项(这就是变更的引入)。产品经理根据需要评估待定项并修改优先级。
冲刺(sprint) ——一些工作单元组成,这些工作单元是达到待定项中定义的需求所必需的,并且必须能在预定的时间段( time-box9)内(一般情况下为30天)完成。冲刺过程中不允许有变更(例如积压工作项)。因此,冲刺给开发团队成员的工作提供了短期但稳定的环境。
Scrum例会——Serum 团队每天召开的短会(一般情况为15分钟),会上所有成员要回答三个问题[Noy02]:
燃尽图:衡量在一个Sprint时间段内剩余的Sprint待办事项列表条目。
七个任务:起始、获取、细化、协商、规格说明、确认、管理
1.起始(Inception): 在项目起始阶段,要建立基本的理解,包括对问题、谁需要解决方案、所期望解决方案的性质、与项目利益相关者和开发人员之间达成初步交流合作的效果。
2.获取(Elicitation –gathering requirements): 询问客户、用户和其他人,系统或产品的目标是什么,想要实现什么,系统和产品如何满足业务的要求,最终系统或产品如何利用于日常工作。
3.细化(Elaboration-requirement modeling): 在起始和导出阶段获得的信息将在精化阶段进行扩展和提炼该任务集中于开发一个精确的需求模型。
4.协商(Negotiation-win-win): 使用迭代的方法给需求排序,评估每项需求对项目产生的成本和风险,表述内部冲突,删除、组合和修改需求,以便参与各方均能达到一定的满意度,实现双赢。
5.规格说明(Specification-document,Model,prototype): 一个规格说明可以是一份写好的文档、一套图形化的模型、一个形式化的数学模型、一组使用场景、一个原型或上述各项的任意组合。
6.确认(Validation-Quality assess): 在确认这一步对需求工程的工作产品进行质量评估。
7.需求管理(Management-Change): 基于计算机的系统其需求会变更,并且变更的要求贯穿于系统的整个生存期。需求管理是用于帮助项目组在项目进展中标识、控制和跟踪需求以及需求变更的一组活动。
确认利益相关者
“你认为我还需要和谁交谈
识别多重观点
协同合作:标识公共区域和矛盾区域、优先点法解决需求
首次提问
谁是这项工作的最初请求者?
谁将使用该解决方案?
成功的解决方案将带来什么样的经济收益?
对于这个解决方案你还需要其它资源吗?
协作收集需求:
会议由软件工程师和其他的共利益者共同举办和参与
制定筹备和参与会议的规则
拟定一个会议议程
由一个“主持人”(可以是客户、开发人员或其他人)控制会议
采用“方案论证手段”(可以是工作表、活动挂图、不干胶贴纸或电子公告牌、聊天室或虚拟论坛)
目标是标识问题,提出解决方案的要素,协商不同方法以及确定一套解决需求问题的初级方案
用例模板:用例、主要参与者、目标、前提条件、触发器、场景、异常、优先级、何时可用、使用频率、使用方式、次要参与者、次要参与者使用方式、未解决的问题
使用基于场景的方法可以从用户的视角描述系统。
开发用例图时,应列出特定参与者执行的功能或活动。
例:
UML活动图在特定场景通过提供迭代流的图形表示来补充用例。
例:
UML泳道图是活动图的一种有用变化,可以让建模人员表示用例所描述的活动流,同时指示哪个参与者或分析类是由活动矩形所描述的活动来负责。
基于类建模表示了系统操作的对象、应用于对象间能有效控制的操作、这些对象间的关系以及已定义类之间的协作。
基于类的分析模型包括类和对象、属性、操作、类的职责协作者(CRC)模型、协作图和包。
识别分析类
外部实体(其他系统、设备、人员),产生或实验基于计算机系统的信息。
事物(报告、显示、字母、信号),问题信息域的一部分。
偶发事件或事件(所有权转移或完成机器人的一组移动动作),在系统操作环境内发生。
角色(经理,工程师,销售人员),由和系统交互的人员扮演
组织单元(部门,组,团队),和某个应用系统相关
场地(制作车间或码头),建立问题的环境和系统的整体功能
结构(传感器、交通工具、计算机),定义了对象的类或与对象相关的类。
例:
类-职责-协作者建模(CRC)
CRC模型实际上是表示类的标准索引卡片的集合。
顶部写类名,左侧列出类的职责,右侧部分列出了类的协作者。
类:
Entity classes 实体类:一般代表保存在数据库中和贯穿应用程序的事物。
Boundary classes 边界类:创建用户可见的和在使用软件时交互的接口
Controller classes 控制类:管理“控制单元”
职责:
职责的基本原则:
1.智能系统应分布哎所有类中以求最佳地满足问题的需求。
2.每个职责的说明应尽可能具有普遍性。
3.信息和与之相关的信息应局限于一个类中而不要分布在多个类中。
4.信息和与之相关的行为应该放在同一类中。
5.适合时,职责应由相关类共享。
属性:描述了已经选择包含在需求模型中的类
操作:定义了某个对象的行为。
生成行为模型的步骤:
1.评估所有的用例,以保证完全理解系统内的交互顺序
2.识别驱动交互顺序的事件,并理解这些事件如何与特定的对象相互关联
3.为每个用例生成序列
4.创建系统状态图
5.评审行为模型以验证准确性和一致性。
状态图:
UML状态图就是一种行为模型,该图为每个类呈现了主动状态和导致这些主动状态变化的事件。
例:
1.抽象(Abstraction):
过程抽象是指具有明确和有限的指令序列(描述动作)
数据抽象是描述数据对象的冠名数据集合(描述动作怎么做)
2.体系结构(Architecture):软件的整体结构和这种结构为系统提供概念完整方式。构件表示主要的系统元素及其交互。
3.模式(Patterns):模式承载了已证实的解决方案的精髓。设计模式描述了在某个特定场景与可能影响模式应用和使用方法的“影响力”中解决某个特定的设计问题的设计结构。
4.关注点分离(Separation of concerns):它表明任何复杂问题如果被分解为可以独立解决和优化的若干块,该复杂问题能够更容易的被处理。
5.模块化(Modularity):模块化是关注点分离最常见的表现。软件被划分为独立命名的、可处理的构件,有时被称为模块,把这些构件集成到一起可以满足问题的需求。模块化设计使得开发工作更易规划。
6.信息隐蔽(Hiding):隐蔽意味着通过定义一系列独立的模块可以得到有效的模块化,独立模块互相之间只交流实现软件功能所必须的那些信息。隐蔽定义并加强了对模块内过程细节的访问约束和对模块所使用的任何局部数据结构的访问约束。
7.功能独立(Functional independence):开发具有“专一”功能和低耦合性的模块即可实现功能独立。
8.求精(Refinement):通过连续精化过程细节层次来实现程序的开发,通过逐步分解功能的宏观陈述直到形成程序设计语言的语句来进行层次开发。
抽象和精化是互补的概念。
9.方面(Aspects):一个方面作为一个独立的模块进行实施,而不是作为“分割的”或者和许多构件“纠缠的”软件片段进行实施。设计体系结构应当支持定义一个方面,该方面即一个模块,该模块能够使该关注点经过它横切的所有其他关注点而得到实施。
10.重构(Refactoring):重构是使用这样一种方式改变软件系统的过程:不改变代码的外部行为而是改进其内部结构。
11.面向对象的设计概念(OO design concepts):
面向对象概念(类、对象、继承、消息和多态)
12.设计类(Design Class):提供设计细节,使程序得以实施。
设计概念强调了:
(1)抽象的必要性,它提供了一种创造可重用软件构件的方法
(2)体系结构的重要性,它使得能够更好地理解系统整体结构
(3)基于模式的工程的有益性,它是一项用于已证明能力的软件的设计技术
(4)关注点分离和有效的模块化的价值,他们使得软件更容易理解、更容易测试以及更容易维护。
(5)信息隐藏的直接作用,当错误发生时,它能够减少负面影响的传播
(6)功能独立的影响,他是构造有效模块的标准
(7)求精作为一种设计方法的作用
(8)横切系统需求方面的考虑
(9)重构的应用,他是为了优化已导出的设计
(10)面向对象的类和与类相关特征的重要性
数据设计元素:数据设计创建在高级抽象级上表示的数据模型和信息模型。
体系结构设计元素:体系结构设计元素通常描述为一组相互关联系统的子系统,且常常从需求模型中的分析包中派生出来。
接口设计元素:软件接口设计元素描述了信息如何流入和流出系统以及被定义为体系结构一部分的构件之间是如何通信的。
接口设计有3个重要的元素:
(1)用户界面
(2)和其他系统、设备、网络或其他信息生成者或使用者的外部接口
(3)各种设计构件之间的内部接口
构件级设计元素:软件的构件级设计完整地描述了每个软件构件的内部细节。构件级设计为所以局部数据对象定义数据结构,为所有在构件内发生的处理定义算法细节,并定义允许访问所有构件操作的接口。
部署级设计元素: 部署级设计元素指明软件功能和子系统将如何在支持软件的物理计算环境内分布。
程序或计算机系统的软件体系结构是指系统的一个或者多个结构,它包括软件构件、构件的外部可见属性以及它们之间的相互联系。
体系结构并非可运行的程序。
确切的说,它是一种表达,是能够:
(1)对设计在满足既定需求方面的有效性进行分析
(2)在设计变更相对容易的阶段,考虑体系结构可能的选择方案
(3)降低与软件构造相关的风险
体系结构重要的3个关键原因
1.软件体系结构的表示有助于对计算机系统开发感兴趣的各方展开交流。
2.体系结构突出了早期的设计决策,这些决策对随后所有的软件工程工作有深远影响,同时对系统作为一个可运行实体的最后成功有重要作用。
3.体系结构“构建了一个相对小的、易于理解的模型,该模型描述了系统如何构成以及其构件如何一起工作”
体系结构风格:
1.构件是计算机软件中的一个模块化的构造块。
2.OMG定义构件:系统中模块化的、可部署的和可替换的部件,该部件封装了实现并暴露一组接口。
构件包括一组协作的类。
传统观点(Traditional View):
一个构件就是程序的一个功能要素,程序由处理逻辑及实现处理逻辑所需的每部数据结构以及能够保证构件被调用和实现数据传递的结构构成。
开闭原则:模块应该对外延具有开放性,对修改具有封闭性。
依赖倒置原则:依赖于抽象,而非具体实现。
Liskov替换原则:子类可以替换他们的基类。
接口分离原则:多个客户专用接口比一个通用接口好
发布复用等价性原则:复用的粒度就是发布的粒度
共同封装原则:一同变更的类应该合在一起
共同复用原则:不能一起复用的类不能被分到一组
内聚性意味着构件或者类只封装那些相互关联密切,以及与构件或类自身有亲密关系的属性和操作。
功能内聚:主要通过操作来体现,当一个模块只完成某一组特定操作并返回结果时,就称此模块是功能内聚的。
分层内聚:高层能够访问低层的服务,但低层不能访问高层的服务。
通信内聚:访问相同数据的所有操作被定义在同一个类中。(数据的查询,访问,存储)
耦合是类之间彼此联系程度的一种定性度量。
随着类(构件)相互依赖越来越多,类之间的耦合程度亦会增加。
内容耦合:暗中修改其他构件的内部数据,这违反了信息隐蔽原则
公用耦合:当大量的构件都要使用同一个全局变量时发生这种耦合
控制耦合:当操作A调用操作B,并向B传递控制标记时,就会发生这种耦合。
标记耦合:当类B被声明为类A某一操作中的一个参数类型时,就会发生这种耦合。
数据耦合:当操作需要传递长串的数据参数时,就会发生这种耦合。
例程调用耦合:当一个操作调用另一个操作时,就会发生这种耦合。
类型使用耦合:当构件A使用了在构件B中定义的一个数据类型时,就会发生这种耦合。
包含或者导入耦合:当构件A引入或者包含一个构件B的包或者内容时,就会发生这种耦合。
外部耦合:当一个构件和基础设施构件进行通信和协作时,就会发生这种耦合。
为什么要高内聚?
模块之间的关系越紧密,出错就越少!
为什么要低耦合?
子程序间的关系越复杂,就会产生更多的意想不到的错误!会给以后的维护工作带来很多麻烦!
高内聚低耦合,是软件工程中的概念,是判断设计好坏的标准,主要是面向对象的设计,主要是看类的内聚性是否高,耦合度是否低。
黄金准则
1.用户操纵控制
(1)以不强迫用户进入不必要的或不希望的动作的方式来定义交互模式
(2)允许用户交互被中断和撤销
(3)当技能级别增长时可以使交互流线化并允许定制交互
(4)使用用户与内部技术细节隔离开来
(5)设计应允许用户与出现在屏幕上的对象直接交互
2.减少用户的记忆负担
(1)减少对短期记忆的要求
(2)建立有意义的缺省
(3)定义直观的快捷方式
(4)以不断进展的方式揭晓信息
3.保持界面一致
(1)允许用户当前任务放入有意义的环境中
(2)在应用系统家族内保持一致性
(3)如果过去的交互模型已经建立起了用户期望,除非有迫不得已的理由,doze不要改变它。
可用性
可用性是指用户在使用高科技产品所提供的功能和特性时,对使用的容易程度和有效程度的定量测量。
用户界面的分析与设计
工程师建立用户模型。软件工程师创建设计模型。最终用户在脑海中对界面产生映像,称为用户的心理模型或系统感觉。系统的实现者创建实现模型。
用户模型: 确定了系统最终用户的轮廓。
设计模型: 用户界面的设计
心理模型: 最终用户在脑海里对系统产生的印象。
实现模型: 组合了计算机系统的外在表现,结合了所有用来描述系统语法和语言的支撑信息。
用户界面的分析和设计过程是迭代的,用户界面分析和设计过程开始于螺旋模型的内部,并且包括4个阶段:(1)界面分析及建模。(2)界面设计。(3)界面构造。(4)界面确认。
界面设计的目标是定义一组界面对象和动作,使得用户能够以满足系统所定义的每个使用目标的方式完成所有定义对的任务。
界面分析
在用户界面的设计中,理解问题就意味着了解:
(1)通过界面和系统交互的人
(2)最终用户为完成工作要执行的任务
(3)作为界面的一部分而现实的内容
(4)任务处理的环境
界面分析:
(1)用户分析:
设计师能够将用户心理模型与设计模型聚合在一起的唯一办法就是努力了解用户,以及了解用户是如何使用系统的。
可以从各种途径获得信息
用户访谈:软件团队(代表)与用户讨论。
销售输入:销售人员与用户定期见面。
市场输入:市场分析,分析/理解市场每个部分使用软件的细微差别。
支持输入:技术支持人员与用户访谈。
(2)任务分析与建模
任务分析的目标就是将这些技术应用到用户界面:
a.用例: 用例描述了参与者和系统的交互方式。从用例描述中,软件工程师可以提炼出任务、对象和整个的交互过程。
b.任务细化: 改进了交互流程。任务细化有两种方法:
1.理解实现活动目标而必须完成的任务
2.研究已有的基于计算机的解决方案的规格说明,并且得到一个适应于用户模型、设计模型和系统感觉的用户任务集合。
逐步细化。
c.对象细化: 对象细化标识了接口对象
d.工作流分析: 工作流分析定义了涉及多个人(和角色)时工作流程是如何完成的。
e.层次分析:
用户任务:请求重新填写处方
提供识别信息。
指定名称。
指定用户ID。
指定PIN和密码。
指定处方号码。
指定日期重填是必需的。
软件工程方法:
需求和设计部分提供了一系列概念和方法,可帮助我们获得对问题:合理完整的理解和综合性设计,从而为构建活动建立了坚实的基础。如果应用这些概念,并采取适当的分析和设计方法,那么创建高质量软件的可能性将大大提高。
项目管理技术:
如果(1)项目经理使用估算以确认交付日期是可以达到的;(2)进度依赖关系是清楚的,团队能够抵抗走捷径的诱惑; (3)进行了风险规划,这样出了问题就不会引起混乱,软件质量将受到积极的影响。
此外,项目计划应该包括明确的质量管理和变更管理技术。导致良好项目管理实践的技术将在本书第四部分讨论。
质量控制:
质量控制包括一套软件工程活动,以帮助确保每个工作产品符合其质量目标。评审模型以确保它们是完整的和一致的。检查代码,以便在测试开始前发现和纠正错误。应用一系列的测试步骤以发现逻辑处理、数据处理以及接口通信中的错误。当这些工作成果中的任何-一个不符合质量目标时,测量和反馈的结合使用使软件团队可以调整软件过程。
质量保证:
质量保证建立基础设施,以支持坚实的软件工程方法,合理的项目管理和质量控制活动——如果你打算建立高品质软件,那么所有这些都是关键活动。此外,质量保证还包含一组审核和报告功能,用以评估质量控制活动的有效性和完整性。质量保证的目标是为管理人员和技术人员提供所需的数据,以了解产品的质量状况,从而理解和确信实现产品质量的活动在起作用。
软件可靠性:
可靠性的简单测量是平均失效间隔时间(MTBF)
MTBF = MTTF + MTTR
(即平均失效时间+平均维修时间)
软件可用性:
可用性 = MTTF/(MTTF+MTTR)* 100%
MTBF可靠性测量队MTTF和MTTR同样敏感。而可用性测量在某种程度上对MTTR更为敏感,MTTR是对软件可维护性的间接测量。
测试:测试是在交付给最终用户之前以特定意图找出错误为目的来执行程序的过程。
验证与确认(Verification and Validation,V&V):
验证是指确保软件正确地实现某一特定功能的一系列活动。也即“我们在正确的构建产品吗”
确认是指确保开发的软件可追溯到客户需求的另外一系列活动。也即“我们在构建正确的产品吗”
目的:充分利用测试技术,运行构件中每个控制结构的特定路径,以确保路径的完全覆盖,并最大可能地发现错误。
在单元测试期间,选择测试的执行路径是最基本的任务。
边界测试是最重要的单元测试任务之一。
单元测试过程:
驱动模块:接收测试用例数据,将这些数据传递给构件,并输出结果。
桩模块:替换那些从属于被测构件的模块
当设计高内聚的构件时,就可以简化单元测试。当构件只强调一个功能时,测试用例数就会降低,且比较容易预见错误和发现错误。
集成测试是构造软件体系结构的系统化技术,同时也是进行一些旨在发现与接口相关的错误的测试。
目标是利用已通过单元测试的构件建立设计中描述的程序结构。
集成策略:
回归测试:重新执行已测试过的某些子集,以确保变更没有传播不期望的副作用。
回归测试有助于保证变更不引入无意思行为或额外的错误。
回归测试可以手工进行,方法是重新执行所以测试用例的子集,或者利用捕捉/回放工具自动进行。
捕捉/回放工具使软件工程师能够为后续的回放与比较捕捉测试用例和测试结果。回归测试套件(将要执行的测试子集)包含以下三种测试用例:
能够测试软件所有功能的具有代表性的测试样本。
额外测试,侧重于可能会受变更影响的软件功能。
侧重于已经发生变更的软件构件测试。
冒烟测试:(滚动的集成测试方法,需每天进行重构或加入新的构件)
活动:
1.已经被翻译为代码的软件构件被集成到构造( “build” )中。
一个构造包括所有的数据文件、库、可重用的模块、以及工程化的构件,其中一个构件需要实现一项或多项产品功能。
2.设计一系列测试来揭示错误,使得此构造不能正确地执行其功能。
目的是揭示“显示阻塞” 错误,这种错误最有可能使软件项目滞后于进度计划。
3.将此构造与其他构造集成在一起,每天都对整个产品(以其当前的形式)进行冒烟测试。集成方法可以是自顶向下,也可以是自底向上。
优点:1.降低了集成风险;
2.提高最终产品的质量;
3.简化错误的诊断和修正;
4.易于评估进展状况
**自顶向下集成:自顶向下集成测试是一种构造软件体系结构的增量方法。从主控模块开始,沿着控制层次逐步向下。
自顶向下集成过程:
1.主控模块作为测试驱动模块,用桩模块代替直接附属的下层模块;
2.根据所选的集成策略(深度优先/广度优先),每次用一个实际模块替换一个桩模块;
3.每集成一个模块都进行测试;
4.完成每个测试集之后,用实际模块替换另一个桩模块;
5.可以进行回归测试(即全部或部分地重复已做过的测试),以避免引入新错误。
回到第2步继续执行此过程,直到完成整个程序结构的构造。
**自底向上集成测试:就是从原子模块(程序结构的最底层构件)开始进行构造和测试。
自底向上集成测试过程:
1.连接底层构件以构成完成特定子功能的簇。
2.编写驱动模块(测试的控制程序)以协调测试用例的输入和输出
3.测试簇
4.去掉驱动程序,沿着程序结构向上逐步连接簇
**面向对象软件的测试策略
面向对象软件的类测试等同于传统软件的单元测试。
不同的是:
传统软件单元测试侧重于模块的算法细节和模块接口数据;
面向对象类的测试侧重于封装在该类中的操作和类的状态行为。
封装的类是单元测试的重点,但不再孤立地对单个操作进行测试,而是将其作为类的一部分。
簇测试时面向对象软件集成测试中的一个步骤。
确认测试准则:软件确认是通过一系列表明与软件需求相符合的测试而获得的。
系统测试实际上是对整个基于计算机的系统进行一系列不同考验的测试。所有测试都是为了验证系统成分已经正确地集成在一起,并且完成了指派的功能。
恢复测试:通过各种方式强制让软件以各种方式失败并验证恢复是否正确执行。
** 安全测试:**安全测试验证建立在系统内的保护机制是否能够实际保护系统不受非法入侵。
** 压力测试:**压力测试的目的是是软件面对非正常的情形。是一种要求以非正常数量、频率或容量的方式进行彻底评估。
** 性能测试:**性能测试用来测试软件在集成环境中的运行性能。
** 部署测试:**有时也将部署测试称为配置测试,是在软件将要在其中运行的每一种环境中测试软件。
调试( debugging)出现在成功的测试之后。也就是说,当测试用例发现错误时,调试是使错误消除的过程。尽管调试可以是也应该是一个有序的过程,但它仍然需要很多技巧。当评估测试结果时,软件工程师经常面对的是软件问题表现出的“症状”,即错误的外部表现与其内在原因之间可能并没有明显的关系。调试就是探究错误的外部表现与其内在原因之间关系的智力过程。
测试是发现错误,调试是找错误的原因
测试传统的应用系统
白盒测试是在了解模块内部结构的情况下进行的测试。
利用白盒测试方法导出的测试用例可以:
(1)保证一个模块中的所有独立路径至少被执行一次。
(2)对所有的逻辑判定均需要测试取真和取假两个方面。
(3)在上下边界及可操作的范围内执行所有的循环。
(4)检验内部数据结构以确保其有效性。
基本路径测试:基本路径测试是由TOM首先提出的一种白盒测试技术。
流图(程序图)是一种简单的控制流表示方法。
流程图用于描述程序的控制结构。
将流程图映射为相应的流图。
独立程序路径:
独立路径是指任何贯穿程序的、至少引入一组新语句或一个新条件的路径。
如果设计测试以强迫执行这些路径(基本集合:不唯一),则可以保证程序中的每条语句至少执行一次,且每个条件的取真和取假都被执行。
环复杂度:是一种软件度量,它为程序的逻辑复杂度提供了一个量化的标准。
环复杂性的值定义了程序基本集合中的独立路径数,并提供保证所有语句至少执行一次所需测试数量的上限。
环复杂度的计算:
生成基本测试用例集的步骤:
以设计或源代码为基础,画出相应的流图。
确定所得流图的环复杂性。
V(G)=边-点+2=判定节点数+1=封闭区域数+1
确定线性独立路径的基本集合。
准备测试用例,强制执行基本集合中的每条路径。
黑盒测试也称为行为测试,侧重软件的功能需求。
黑盒测试使软件工程师能设计出将测试程序所有功能需求的输入条件集。
黑盒测试不是白盒测试的替代品,而是作为发现其他类型错误的辅助方法。
黑盒测试试图发现以下类型的错误:
(1)不正确或遗漏的功能
(2)接口错误
(3)数据用在测试的后期阶段
(4)行为或性能错误
(5)初始化和终止错误
等价类划分:是一种黑盒测试方法,它将程序的输入划分为若干个数据类,从中生成测试用例。
等价类表示输入条件的一组有效的或无效的状态。
设计等价类的指导原则:
1.若输入条件指定一个范围,则可以定义一个有效等价类和两个无效等价类。
2.若输入条件需要特定的值,则可以定义一个有效等价类和两个无效等价类。
3.若输入条件指定集合的某个元素,则可以定义一个有效等价类和一个无效等价类。
4.若输入条件为布尔值,则可以定义一个有效等价类和一个无效等价类。
通过运用设计等价类的指导原则,可以为每个输入域数据对象设计测试用例并执行。选择测试用例以便一次测试一个等价类的尽可能多的属性。
边界值分析(BVA):
原因:大量错误发生在输入域的边界处,而不是发生在输入域的“中间”。
边界值分析是对“等价划分”的补充,不是选择等价类的任何元素,而是在等价类“边缘”上选择测试用例。
基线:
基线是一个软件配置管理概念,它能帮助我们在不严重阻碍合理变更的条件下控制变更。
基线的定义:已经经过正式评审和批准的规格说明或产品,它可以作为进一步开发的基础,并且只有通过正式的变更控制规程才能修改它。(即经过评审和批准,不能随意改变的规格说明或者产品)
软件配置项:
软件配置项是在软件工程过程中创建的信息。在极端情况下,大型规格说明中的一节或大型测试用例集中的一个测试用例都可以看作一个SCI。再实际点,一个SCI可以是工作产品的全部或部分(一份文档、一整套测试用例,或者是一个已经命名的程序构件)。
将SCI组织成配置对象,这些配置对象有自己的名字,并且按类别存储在项目数据库中。
SCM中心存储库:
特征和内容:中心存储库存储什么,以及中心存储库提供什么特定服务。
SCM特征:
版本控制:
保存所有这些版本,以便有效地管理产品发布,并允许开发者在测试和调试过程中可以返回到早先的版本。
依赖性跟踪和变更管理:
中心存储库要管理所存储的配置对象之间的各种关系。
需求跟踪:
可以跟踪由特定需求规格说明产生的所有设计构件、架构构件以及可交付产品;
配置管理:
能够跟踪表示特定项目里程碑或产品发布的一系列配置。版本管理提供所需要的版本,链路管理跟踪依赖关系。
审核跟踪:
审核跟踪使我们能够了解变更是在什么时候、什么原因以及由谁完成等信息。
SCM过程:
版本控制:
版本控制结合了规程和工具,可以用来管理在软件过程中所创建的配置对象的不同版本。
版本控制系统实现或者直接集成了4个主要功能:
存储所有相关配置对象的项目数据库(中心存储库) ;
存储配置对象所有版本(或能够通过与先前版本间的差异来构造任何一个版本)的版本管理功能;
使软件工程师能够收集所有相关配置对象和构造软件特定版本的制作功能。
版本控制和变更控制系统通常还有问题跟踪(也叫做错误跟踪)功能,使团队能够记录和跟踪与每个配置对象相关的重要问题的状态。
变更控制:(项目级变更控制,和之前的基线化SCI可以联系起来)
基于过程算的是每个过程需要多少人,本例中是46 人月,按照每个人的劳动力价格计算总成本(分析:设计:编码:测试 = 1 : 4 : 1 : 4)
基于用例的估算:
UCP = ( UUCW + UAW ) * TCF * ECF
UCP:用例点
UUCW:加权后的用例数量求和得到总体的未调整用例权重。
复杂用例描述 * 15
一般用例描述 * 10
简单用例描述 * 5
UAW:将加权后的参与者数量求和得到总体的未调整的参与者权重。
复杂参与者 * 3
一般参与者 * 2
简单参与者 * 1
TCF:技术复杂性因子
ECF:环境复杂性因子
计算用例点,根据经验确定每个用例点需要多少代码,得到总代码量,用劳动力价格除以该系统的平均生产率,即可得到每行代码的成本,乘以总代码量即可得到总估算值。