[软考中级]软件设计师-软开基础知识(1)

4dBmk 笔记 0 次阅读 发布于 2026-09-01 最后更新于 13 小时前 15231 字 预计阅读时间: 1 小时


零、CMM和CMMI

CMM模型(软件开发成熟度模型-5级)

级别(低->高)内容
1.初始级:杂乱无章,甚至混乱,几乎没有明确定义的步骤,项目的成功完全依赖个人的努力和英雄式核心人物的作用
2.**可重复级:**级:建立了基本的项目管理过程和实践来跟踪项目费用、进度和功能特性,有必要的过程准则来重复以前在同类项目中的成功。
3.已定义级:管理和工程两方面的软件过程已经文档化、标准化,并综合成整个软件开发组织的标淮过程。
4.已管理级:制定了软件过程和产品质量的详细度量标准。
5.优化级:加强了定量分析,通过来自过程质量反馈和来自新观念、新技术的反馈使过程能不断持续地改进。
image-20250925175044114

CMM-I模型(软件开发成熟度 集成 模型-6级)

等级CL说明
CL0(未完成的)过程域耒执行或未得到 CLI 中定义的所有目标。
CL1(已执行的)其共性目标是过程将可标识的入工作产品转换成可析识的出工作产品,以实现支持过程域的特定目标。
CL2(已管理的)其共性目标是集中于已理的过程的制度化。
CL3 (已定义级的)其共性目标集中于已定义的过程的制度化。
CL4(定量管理的)其共性目标集中于可定量管理的过幄的制度化。
CL5(优化的)使用量化(统计学)手段改变和优化过程域,以满足客户的改变和持续改进计划中的过程域的功效。

PS:CMM-I与CMM模型最大的区别是多了个CL0级,考虑到了未完成的情况

例题

1.以下关于 CMM 的叙述中,不正确的是()

A 、 CMM 是指软件过程能力成熟度模型

B 、 CMM 根据软件过程的不同成熟度划分了 5 个等级,其中, 1 级被认为成熟度最高, 5 级被认为成熟度最低

C、 CMMI的任务是将已有的几个 CMM 模型结合在一起,使之构成“集成模型"

D、 采用更成熟的 CMM 模型,一般来说可以提高最终产品的质量

答案:B,CMM中1级最低,5级最高

2.能力成熟度模型集成 (CMMI) 是若干过程模型的综合和改进。连续式模型和阶段式模型是 CMM |提供的两种表示方法。连续式模型包括 6 个过程域能力等级 (capability Level, CL) ,其中( )的共性目标是过程将可标识的输入工作产品转换成可标识的输出工作产品,以实现支持过程域的特定目柝。

A 、 CL1 (已执行的) B、CL2 〈已管理的)

C 、 CL3 (已定义的) D 、 c L4 〈定量管理的)

答案:A

一、软件开发模型

1.开发生命周期模型

​ 在开发模型知识点中,我们要掌握软件生命周期的概念、各种开发模型的特点和应用场合。主要的开发模型有瀑布模型、增量模型、螺旋模型、喷泉模型、智能模型、V模型、RAD模型、CBSD模型、原型方法、XP方法、RUP方法等。

1.1.瀑布模型

​ 瀑布模型也称为生命周期法,是生命周期法中最常用的开发模型,它把软件开发的过程分为软件计划、需求分析、软件设计、程序编码、软件测试和运行维护6个阶段,规定了它们自上而下、相互衔接的固定次序,如同瀑布流水,逐级下落。采用瀑布模型的软件过程如图

image-20240415133228288

(1)软件计划(问题的定义及规划):主要确定软件的开发目标及其可行性。

(2)需求分析:在确定软件开发可行的情况下,对软件需要实现的各个功能进行详细分析。需求分析阶段是一个很重要的阶段,这一阶段做得好,将为整个软件开发项目的成功打下良好的基础。

(3)软件设计:主要根据需求分析的结果,对整个软件系统进行设计,如系统框架设计、数据库设计等。软件设计一般分为**总体设计(概要设计)**和 详细设计。

(4)程序编码:将软件设计的结果转换成计算机可运行的程序代码。在程序编写中必须制定统一、符合标准的编写规范,以保证程序的可读性,易维护性,提高程序的运行效率。

(5)软件测试:在软件设计完成后要经过严密的测试,以发现软件在整个设计过程中存在的问题并加以纠正。在测试过程中需要建立详细的测试计划并严格按照测试计划进行测试,以减少测试的随意性。

(6)软件维护:软件维护是软件生命周期中持续时间最长的阶段。在软件开发完成并投入使用后,由于多方面的原因,软件不能继续适应用户的要求,要延续软件的使用寿命,就必须对软件进行维护。

​ 瀑布模型是最早出现的软件开发模型,在软件工程中占有重要的地位,它提供了软件开发的基本框架。瀑布模型的本质是“一次通过” ,即每个活动只做一次,最后得到软件产品,也称做“线性顺序模型”或者“传统生命周期” 。

​ 其过程是从上一项活动接收该项活动的工作对象作为输入,利用这一输入实施该项活动应完成的内容,给出该项活动的工作成果,作为输出传给下一项活动;对该项活动实施的工作进行评审,若其工作得到确认,则继续下一项活动,否则返回前项,甚至更前项的活动进行返工。

优点:

(1) 有利于大型软件开发过程中人员的组织与管理

(2)有利于软件开发方法和工具的研究与使用,从而提高了大型软件项目开发的质量和效率。

缺陷:

​ 软件开发的实践表明,上述各项活动之间并非完全是自上而下的,而是呈线性图示

(1)由于开发模型呈线性,所以当开发成果尚未经过测试时,用户无法看到软件的效果。这样,软件与用户见面的时间间隔较长,也增加了一定的风险。

(2)在软件开发前期未发现的错误传到后面的开发活动中时,可能会扩散,进而可能导致整个软件项目开发失败。

(3)在软件需求分析阶段,完全确定用户的所有需求是比较困难的,甚至可以说是不太可能的。

1.2.变换模型(演化模型)

​ 变换模型(演化模型)是在快速开发一个原型的基础上,根据用户在调用原型的过程中提出的反馈意见和建议,对原型进行改进,获得原型的新版本,重复这一过程,直到演化成最终的软件产品。

1.3.螺旋模型

​ 螺旋模型将瀑布模型和变换模型相结合,它综合了两者的优点,并增加了风险分析。它以原型为基础,沿着螺线自内向外旋转,每旋转一圈都要经过制订计划、风险分析、实施工程、客户评价等活动,并开发原型的一个新版本。经过若干次螺旋上升的过程,得到最终的系统

特别适用于庞大、复杂并且具有高风险的系统。

image-20240415134239867

1.4.喷泉模型-以对象驱动

​ 喷泉模型对软件复用和生命周期中多项开发活动的集成提供了支持,主要支持面向对象的开发方法。 "喷泉"一词本身体现了迭代和无间隙特性。系统某个部分常常重复工作多次,相关功能在每次迭代中随之加入演进的系统。所谓无间隙是指在开发活动中,分析、设计和编码之间不存在明显的边界

特点:迭代无间隙

image-20240415134456857

1.5.V模型

​ 在开发模型中,测试常常作为亡羊补牢的事后行为,但也有以测试为中心的开发模型,那就是V模型。V模型只得到软件业内比较模糊的认可。V模型宣称测试并不是一个事后弥补行为,而是一个同开发过程同样重要的过程

image-20250925180535503
image-20240415134553644

(1)单元测试的主要目的是针对详细设计过程中可能存在的各种错误。例如:用户输入验证过程中的边界值的错误。

(2)集成测试的主要目的是针对概要设计中可能存在的问题,尤其是检查各单元与其他程序部分之间的接口上可能存在的错误。

(3)系统测试主要针对需求分析,检查系统作为一个整体是否有效地得到运行。例如:在产品设置中是否达到了预期的高性能。

(4)验收测试通常由业务专家或甲方用户进行,以确认产品能真正符合用户业务上的需要。

1.6.增量模型(快速原型模型)

​ 增量模型融合了瀑布模型的基本成分(重复的应用)和原型实现的迭代特征。

​ 增量模型采用随着时间的进展而交错的线性序列,每一个线性序列产生软件的一个可发布的"增量“.

​ 当使用增量模型时,第一个增量往往是核心需求,也就是说第一个增量实现了基本的需求,但很多补充的特征还没有发布。

​ 客户对每一个增量的使用和评估,都作为下一个增量发布的新特征和功能。这个过程在每一个增量发布后不断重复,直到产生最终的完善产品。增量模型强调每一个增量均发布一个可操作的产品。

image-20240415134920118
优点

人员分配灵活 ,刚开始不用投入大量人力资源 ,如果核心产品很受欢迎 ,则可以增加人力实现下一个增量;

当配备的人员不能在设定的期限内完成产品时 ,它提供了一种先推出核心产品的途径 ,这样就可以先发布部分功能给客户 ,对客户起到镇静剂的作用。

此外 ,增量能够有计划地管理技术风险。

缺点

如果增量包之间存在相交的情况且不能很好地处理 ,就必须做全盘的系统分析。

适用于:

增量模型将功能细化、分别开发的方法适用于需求经常改变的软件开发过程。

1.7.RAD模型

​ 快速应用开发(Rapid Application Development,RAD)模型是一个增量型的软件开发过程模型,强调极短的开发周期。RAD模型是瀑布模型的一个“高速”变种,通过大量使用可复用构件,采用基于构件的建造方法赢得快速开发。

​ 如果需求理解得好且约束了项目的范围,利用这种模型可以很快地创建出功能完善的“信息系统“ 。其流程从业务建模开始,随后是数据建模、过程建模、应用生成、测试及反复。采用RAD模型的软件过程如图所示。

image-20240415153253144

(1)业务建模:以什么信息驱动业务过程运作?要生成什么信息?谁生成它?信息流的去向是哪里?由谁处理?可以辅之以数据流图。

(2)数据建模:为支持业务过程的数据流,找数据对象集合,定义数据对象属性,与其他数据对象的关系构成数据模型,可辅之以E-R图。

(3)过程建模:使数据对象在信息流中完成各业务功能。创建过程以描述数据对象的增加、修改、删除、查找,即细化数据流图中的处理框。

(4)应用程序生成:利用**第四代语言(4GL)**写出处理程序,重用已有构件或创建新的可重用构件,利用环境提供的工具自动生成并构造出整个应用系统。

(5)测试与交付,由于大量重用,一般只做总体测试,但新创建的构件还是要测试的。

与瀑布模型区别:
瀑布模型RAD模型
使用语言传统的第三代程序设计语言是采用基于构件的开发方法,复用已有的程序结构(如果可能的话)或使用可复用构件,或创建可复用的构件(如果需要的话)

​ 在所有情况下,均使用自动化工具辅助软件创造。很显然,加在一个RAD模型项目上的时间约束需要"一个可伸缩的范围".如果一个业务能够被模块化使得其中每一个主要功能均可以在不到三个月的时间内完成,那么它就是RAD的一个候选者。每一个主要功能可由一个单独的RAD组来实现,最后再集成起来形成一个整体

优点:

(1)RAD模型通过大量使用可复用构件加快了开发速度,对信息系统的开发特别有效。

缺陷:

(1)并非所有应用都适合RAD.RAD模型对模块化要求比较高,如果有哪一项功能不能被模块化,那么建造RAD所需要的构件就会有问题;如果高性能是一个指标,且该指标必须通过调整接口使其适应系统构件才能赢得,RAD方法也有可能不能奏效。

(2)开发者和客户必须在很短的时间完成一系列的需求分析,任何一方配合不当都会导致RAD项目失败。

(3)RAD只能用于信息系统开发,不适合技术风险很高的情况。当一个新应用要采用很多新技术或当新软件要求与已有的计算机程序有较高的互操作性时,这种情况就会发生。

1.8.基于构件的模型

​ 构件(Component,组件)是一个具有可重用价值的、功能相对独立的软件单元。基于构件的软件开发(Component Based Software Development,CBSD)模型是利用模块化方法,将整个系统模块化,并在一定构件模型的支持下,复用构件库中的一个或多个软件构件,通过组合手段高效率、高质量地构造应用软件系统的过程。基于构件的开发模型融合了螺旋模型的许多特征,本质上是演化型的,开发过程是迭代的。

​ 基于构件的开发模型由软件的需求分析和定义、体系结构设计、构件库建立、应用软件构建、测试和发布5个阶段组成。

image-20240415160339735
优点

​ 基于构件的开发方法使得软件开发不再一切从头开始,开发的过程就是构件组装的过程,维护的过程就是构件升级、替换和扩充的过程,其优点是:

(1)构件组装模型导致了软件的复用,提高了软件开发的效率;

(2)构件可由一方定义其规格说明,被另一方实现,然后供给第三方使用;

(3)构件组装模型允许多个项目同时开发,降低了费用,提高了可维护性,可实现分步提交软件产品。

缺点

(1)是由于采用自定义的组装结构标准,缺乏通用的组装结构标准,引入具有较大的风险;

(2)可重用性和软件高效性不易协调,需要精干的、有经验的分析人员和开发人员,一般的开发人员插不上手,客户的满意度低;

(3)过分依赖于构件,构件库的质量影响着产品质量。

1.9.原型方法

​ 软件原型是所提出的新产品的部分实现,建立原型的主要目的是为了解决在产品开发的早期阶段的需求不确定的问题,其目的是明确并完善需求、探索设计选择方案、发展为最终的产品。

​ 原型有很多种分类方法。从原型是否实现功能来分,软件原型可分为水平原型和垂直原型两种。

水平原型(行为原型)垂直原型(结构化原型)
用途用来探索预期系统的一些特定行为,并达到细化需求的目的
内容只是功能的导航,但并未真实实现功能实现了一部分功能
作用于主要用在界面上主要用在复杂的算法实现上
image-20240415161649041

​ 从原型的最终结果来分,软件原型可分为抛弃型原型和演化型原型。

抛弃型原型(探索型原型)演化型原型
达到预期目的后,原型本身被抛弃为开发增量式产品提供基础,是螺旋模型的一部分,也是面向对象软件开发过程的一部分
主要用在解决需求不确定性、二义性、不完整性、含糊性等必须易于升级和优化的项目,适用于Web项目。

​ 有些文献把原型分为实验型、探索型和演化型。

实验型探索型演化型
目的用于大规模开发和实现之前,考核方案是否合适,规格说明是否可靠弄清对目标系统的要求,确定所希望的特性,并探讨多种方案的可行性目的不在于改进规格说明,而是将系统建造得易于变化,在改进原型的过程中,逐步将原型进化成最终系统。

​ 还有些文献也把原型分为抛弃式原型、演化式原型和递增式原型。


​ 原型法适合于用户没有肯定其需求的明确内容的时候。它是先根据已给的和分析的需求,建立一个原始模型,这是一个可以修改的模型(在生命周期法中,需求分析成文档后一般不再多修改)。

​ 在软件开发的各个阶段都把有关信息相互反馈,直至模型的修改,使模型渐趋完善。在这个过程中,用户的参与和决策加强了,最终的结果是更适合用户的要求。

​ 这种原型技术又可分为三类:抛弃式、演化式和递增式。这种原型法成败的关键及效率的高低在于模型的建立及建模的速度。

1.10.极限编程XP方法-快而精

XP是一种轻量(敏捷)、高效、低风险、柔性、可预测、科学而且充满乐趣的软件开发方式。与其他方法论相比,其最大的不同在于:

(1)在更短的周期内,更早地提供具体、持续的反馈信息。

(2)迭代地进行计划编制,首先在最开始迅速生成一个总体计划,然后在整个项目开发过程中不断地发展它。

(3)依赖于自动测试程序来监控开发进度,并及早地捕获缺陷。

(4)依赖于口头交流、测试和源程序进行沟通。

(5)倡导持续的演化式的设计。

(6)依赖于开发团队内部的紧密协作。

(7)尽可能达到程序员短期利益和项目长期利益的平衡。

如图所示,XP由4大价值观、5大原则、12大实践和行为四个部分组成,它们彼此相互依赖、关联,并通过行为贯穿于整个生命周期

4大价值观(背)5 大原则(理解)12 大最佳实践〈落地案例)
沟通、简单、反馈、勇气快速反馈、简单性假设、逐步修改、提倡更改、优质工作1.计划游戏:只处理当前的需求快速制定计划、随着细壭的不断变化而完善
2.简单设计:使设计保持简单
3.小型发布:系统的设计要能够尽可能早地交付
4.隐喻:找到合适的比喻传达信息
5.测试先行:先写测试代码,然后再写程序
6.重构:重新审视需求和设计,重新明确地描述它们以符合新的和现有的需求
7.结对编程
8.集体代码所有制
9.持续集成:可以按日甚至按小时为客户提供可运行的版本
10.现场客户:系统最终用户代表应该全程配合XP 团队
11.编码标准
image-20240415164921280

XP的核心是其总结的4大价值观 ,即沟通、简单、反馈和勇气。它们是XP的基础 ,也是XP的灵魂。

XP的5个原则是快速反馈、简单性假设、逐步修改、提倡更改和优质工作。而在XP方法论中 ,贯彻的是"小步快走"的开发原则 ,因此工作质量决不可打折扣 ,通常采用测试先行的编码方式来提供支持。

1.11.RUP方法

​ RUP(Rational Unified Process)是一个统一的软件开发过程,是一个通用过程框架,可以应付种类广泛的软件系统、不同的应用领域、不同的组织类型、不同的性能水平和不同的项目规模。RUP是基于构件的,这意味着利用它开发的软件系统是由构件构成的,构件之间通过定义良好的接口相互联系。在准备软件系统所有蓝图的时候,RUP使用的是统一建模语言UML.

特点:

​ 与其他软件过程相比,RUP具有三个显著的特点:用例驱动、以基本架构为中心、迭代和增量。

阶段流程:

​ RUP中的软件过程在时间上被分解为四个顺序的阶段,分别是初始阶段、细化阶段、构建阶段和交付阶段。每个阶段结束时都要安排一次技术评审,以确定这个阶段的目标是否已经满足。如果评审结果令人满意,就可以允许项目进入下一个阶段。基于RUP的软件过程模型如图

image-20250925183508791
image-20250925184534136
image-20240416133202913

​ 图中可以看出 :基于RUP的软件过程是一个迭代过程。通过初始、细化、构建和提交四个阶段就是一个开发周期 ,每次经过这四个阶段就会产生一代软件。 除非产品退役 ,否则通过重复同样的四个阶段 ,产品将演化为下一代产品 ,但每一次的侧重点都将放在不同的阶段上。这些随后的过程称为演化过程。

​ 在进度和工作量方面 ,所有阶段都各不相同。尽管不同的项目有很大的不同 ,但一个中等规模项目的典型初始开发周期应该预先考虑到工作量和进度间的分配 ,如表

image-20240416133453563

​ 对于演进周期 ,初始和细化阶段就小得多了。能够自动完成某些 构建工作的工具将会缓解此现象 ,并使得构建阶段比初始阶段和细化阶段的总和还要小很多。

​ RUP的工作流程分为两部分 :核心工作流程与核心支持工作流程

  1. 核心工作流程(在项目中的流程)包括业务需求建模、分析设计、实施、测试、部署;
  2. 核心支持工作流程(在组织中的流程)包括环境、项目管理、配置与变更管理。

2.系统开发方法论

系统的开发方法主要包括结构化分析与设计、面向数据结构的设计、面向对象分析与设计以及构件化方法四种。

结构化分析与设计面向数据结构的设计面向对象分析与设计构件化开发(原型化)
思想" 自顶向下 ,逐步分解"根据数据结构导出程序结构引入了"对象"的概念为了降低开发费用、提高生产率 ,以及在快速的技术演化面前提供受控的系统升级的开发方式
内容把软件生命周期的全过程依次划分为若干阶段 ,然后顺序地完成每个阶段的任务典型的面向数据结构的设计方法包括Jackson方法和Warnier方法。 Jackson方法的基本步骤 : 先建立系统的数据结构;接着以数据结构为基础 ,对应地建立程序结构;列出程序中要用到的各种基本操作 ,然后将操作分配到适当的模块中去。将数据和方法封装在一起通过有计划地集成现有的软件部分来进行软件开发。 使用预建的构件和模板 ,像"搭积木"式地建造。
特点采用结构化技术 与瀑布模型有很好的结合度 ,是与其最相适应的开发方法没有明显地使用软件结构的概念 ,对于模块独立性原则也重视不足 ,因此并不适合于复杂的软件系统。提高了模块的聚合度 ,降低了耦合度 ,更大程度上支持软件复用。 是现在最流行和最具有发展前景的软件开发方法有效地遏制复杂性、缩短发布时间、提高一致性 ,更有效地利用本领域的最佳方法、提高生产率、增加项目进度的可视性、支持并行和分布式的开发、减少维护费用
适用范围需求清晰层次性结构软件需求不清晰并不断变化、系统规模很大且很复杂需求不清晰并不断变化、系统规模不大且不复杂

2.1.结构化分析与设计

​ 这种方法采用结构化技术来完成软件开发的各项任务。该方法把软件生命周期的全过程依次划分为若干阶段 ,然后顺序地完成每个阶段的任务 ,与瀑布模型有很好的结合度 ,是与其最相适应的开发方法。

​ 结构化方法的核心思想是" 自顶向下 ,逐步分解".

2.2.面向数据结构的设计

​ 数据的输入、存储都涉及不同的数据结构 ,面向数据结构设计方法的基本思想是根据数据结构导出程序结构。典型的面向数据结构的设计方法包括Jackson方法和Warnier方法。

​ Jackson方法的基本步骤 :先建立系统的数据结构;接着以数据结构为基础 ,对应地建立程序结构;列出程序中要用到的各种基本操作 ,然后将操作分配到适当的模块中去。

​ 面向数据结构的设计方法并没有明显地使用软件结构的概念 ,对于模块独立性原则也重视不足 ,因此并不适合于复杂的软件系统。

2.3.面向对象分析与设计

​ 这种方法引入了"对象"的概念 ,将数据和方法封装在一起 ,提高了模块的聚合度 ,降低了耦合度 ,更大程度上支持软件复用。面 向对象方法是现在最流行和最具有发展前景的软件开发方法

2.4.构件化开发

​ 为了降低开发费用、提高生产率 ,以及在快速的技术演化面前提供受控的系统升级的开发方式 ,就催生了基于构件的软件开发( Component-Based Software Development,CBSD )。 它通过有计划地集成现有的软件部分来进行软件开发。 它可以有效地遏制复杂性、缩短发布时间、提高一致性 ,更有效地利用本领域的最佳方法、提高生产率、增加项目进度的可视性、支持并行和分布式的开发、减少维护费用。采用CBSD后 ,所有的软件解决方案将可以使用预建的构件和模板 ,像"搭积木"式地建造。

​ 这种"积木"就是构件(组件) ,构件是一个功能相对独立的具有 可重用价值的软件单元。在面向对象方法中 ,一个构件由一组对象 构成 ,包含了一些协作类的集合 ,它们共同工作来提供一种系统功 能。构件具有5个基本要素 :规格说明、一个或多个实现、受约束 的构件标准、包装方法和部署方法。

​ 可重用性是指系统和(或)其组成部分能在其他系统中重复使用的程度。软件开发的全生命周期都有可重用的价值 ,包括项目的组织、软件需求、设计、文档、实现、测试方法和测试用例 ,都是可以被重复利用和借鉴的有效资源。可重用性体现在软件的各个层次 ,通用的、可复用性高的软件模块往往已经由操作系统或开发工具提供 ,如通用库、标准组件和标准模板库等 ,并不需要程序员重新开发。

二、软件测试

1.测试的目的

​ 软件测试是软件质量保证的主要手段之一,也是在将软件交付给客户之前所必须完成的步骤。目前,软件的正确性证明尚未得到根本的解决,软件测试仍是发现软件错误和缺陷的主要手段。软件测试的目的就是在软件投入生产性运行之前,尽可能多地发现软件产品(主要是指程序)中的错误和缺陷。

(1)软件测试是为了发现错误而执行程序的过程。

(2)测试是为了证明程序有错,而不是证明程序无错误。

(3)一个好的测试用例是在于它能发现至今未发现的错误。

(4)一个成功的测试是发现了至今未发现的错误的测试。

​ 这种观点可以提醒人们测试要以查找错误为中心,而不是为了演示软件的正确功能。但是仅凭字面意思理解这一观点可能会产生误导,认为发现错误是软件测试的唯一目的,查找不出错误的测试就是没有价值的,事实并非如此。

​ 首先,测试并不仅仅是为了要找出错误。通过分析错误产生的原因和错误的分布特征,可以帮助项目管理者发现当前所采用的软件过程的缺陷,以便改进。同时,这种分析也能帮助我们设计出有针对性的检测方法,改善测试的有效性。

​ 其次,没有发现错误的测试也是有价值的,完整的测试是评定测试质量的一种方法。

​ 因此,软件测试可以验证软件是否满足软件需求规格说明和软件设计所规定的功能、性能及其软件质量特性的要求,为软件质量的评价提供依据。我们要注意的是软件测试只是软件质量保证的手段之一,不能单凭测试来保证软件质量。

2.测试的类型

软件测试方法一般分为两大类,分别为动态测试和静态测试。

image-20250926113240003

2.1.动态测试(机器运行)

​ 动态测试指通过运行程序发现错误,分为黑盒测试法、白盒测试法和白盒测试法。不管是哪一种测试,都不能做到穷尽测试,只能选取少量最有代表性的输入数据,以期用较少的代价暴露出较多的程序错误。这些被选取出来的数据就是测试用例(一个完整的测试用例应该包括输入数据和期望的输出结果)。

黑盒法白盒法灰盒法
把被测试对象看成一个黑盒子,测试人员完全不考虑程序的内部结构和处理过程,只在软件的接口处进行测试,依据需求规格说明书,检查程序是否满足功能要求。把测试对象看作一个打开的盒子,测试人员须了解程序的内部结构和处理过程,以检查处理过程的细节为基础,对程序中尽可能多的逻辑路径进行测试,检验内部控制结构和数据结构是否有错,实际的运行状态与预期的状态是否一致。灰盒测试是一种介于白盒测试与黑盒测试之间的测试,它关注输出对于输入的正确性。同时也关注内部表现,但这种关注不像白盒测试那样详细且完整,而只是通过一些表征性的现象、事件及标志来判断程序内部的运行状态。
等价类划分、边值分析、错误猜测、因果图和功能图等基本路径测试、循环覆盖测试、逻辑覆盖测试
灰盒测试结合了白盒测试和黑盒测试的要素,考虑了用户端、特定的系统知识和操作环境,在系统组件的协同性环境中评价应用软件的设计。
image-20250926114906595
2.1.1黑盒法

​ 把被测试对象看成一个黑盒子,测试人员完全不考虑程序的内部结构和处理过程,只在软件的接口处进行测试,依据需求规格说明书,检查程序是否满足功能要求。常用的黑盒测试用例的设计方法有等价类划分、边值分析、错误猜测、因果图和功能图等。

等价类划分(常考)边值分析(常考)错误猜测因果图功能图
测试用例将所有可能的输入数据,划分为等价的部分,然后从每个部分中选取少数有代表性的数据作为测试用例。它是对等价类划分法的一个补充,即选取正好等于、刚刚大于或刚刚小于边界的值作为测试数据。列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据它们选择测试用例。测试用例则是由测试中经过的一系列状态和在每个状态中必须依靠输入/输出数据满足的一对条件组成的。
内容分为有效等价类(即合理、有意义的数据集合)、无效等价类(即不合理、无意义的数据集合)两种首先基于规格说明书分析原因(等价类)和结果(输出条件);然后找出原因与结果之间的关系,画出因果图;在因果图上加上约束或限制条件;将其转换为判定表;根据判定表得出测试用例。它是由状态迁移图和逻辑功能模型构建的,状态迁移图用于表示输入数据序列以及相应的输出数据;逻辑功能模型用于表示在状态中输入条件与输出条件之间的对应关系。
原则和用途在选取测试用例时,应遵从"设计一个新的测试用例时,应尽可能多地覆盖尚未覆盖的有效等价类;但每次应仅覆盖一个尚未覆盖的无效等价类"的原则用来描述多种条件组合的测试用例,其最终生成的结果是判定表。
缺点都只考虑了输入条件,未考虑输入条件间的联系都只考虑了输入条件,未考虑输入条件间的联系
2.1.2白盒法

​ 把测试对象看作一个打开的盒子,测试人员须了解程序的内部结构和处理过程,以检查处理过程的细节为基础,对程序中尽可能多的逻辑路径进行测试,检验内部控制结构和数据结构是否有错,实际的运行状态与预期的状态是否一致。 由于白盒测试是结构测试,所以被测对象基本上是源程序,以程序的内部逻辑为基础设计测试用例。常用的白盒测试用例设计方法有基本路径测试、循环覆盖测试、逻辑覆盖测试

逻辑覆盖测试循环覆盖测试基本路径测试
以程序内部逻辑为基础的测试技术,如常用的语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖、点覆盖、边覆盖、路径覆盖单循环及嵌套循环在程序控制流程图的基础上,通过分析控制构造的环路复杂性导出基本路径集合。然后设计测试用例,保证这些路径至少通过一次
(1)逻辑覆盖:

以程序内部逻辑为基础的测试技术,如常用的语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖、点覆盖、边覆盖、路径覆盖。

语句覆盖判定覆盖(分支覆盖)条件覆盖判定/条件覆盖条件组合覆盖路径覆盖
内容指选择足够多的测试用例,使得运行这些测试用例时,被测程序的每个语句至少执行一次。又称分支覆盖,它的含义是不仅每个语句至少执行一次,而且每个判定的**每种可能的结果(真/假分支)**都至少执行一次。含义是不仅每个语句至少执行一次,而且使判定表达式中的每个条件都取到各种可能的结果。它的含义是选取足够的测试用例,使得判定表达式中每个条件的所有可能取值(真/假)至少出现一次,而且每个判定本身的所有可能结果(真/假)也至少出现一次。含义是选取足够的测试用例,使得每个判定表达式中条件结果的所有可能组合(如a||b的4个情况)都至少出现一次。
然而,条件组合覆盖还不能保证程序中所有可能的路径都至少经过一次。
含义是选取足够的测试用例,使得程序的每条可能执行到的路径都至少经过一次(如果程序中有环路,则要求每条环路径至少经过一次)。
覆盖程度一种很弱的覆盖标准。判定覆盖比语句覆盖强
但对程序逻辑的覆盖程度仍然不高。
条件组合覆盖是上述五种覆盖标准中最强的一种。路径覆盖实际上考虑了程序中各种判定结果的所有可能组合,因此是一种较强的覆盖标准。
与其他覆盖关系条件覆盖不一定包含判定覆盖

判定覆盖也不一定包含条件覆盖。
同时满足判定覆盖和条件覆盖的逻辑覆盖称为判定/条件覆盖。满足条件组合覆盖的测试用例,也一定满足判定/条件覆盖。但路径覆盖并未考虑判定中的条件结果的组合,并不能代替条件覆盖和条件组合覆盖
(2)循环覆盖测试:

​ 单循环及嵌套循环

(3)基本路径测试:

​ 在程序控制流程图的基础上,通过分析控制构造的环路复杂性导出基本路径集合。然后设计测试用例,保证这些路径至少通过一次

2.1.3灰盒法

​ 灰盒测试是一种介于白盒测试与黑盒测试之间的测试,它关注输出对于输入的正确性。同时也关注内部表现,但这种关注不像白盒测试那样详细且完整,而只是通过一些表征性的现象、事件及标志来判断程序内部的运行状态。

​ 灰盒测试结合了白盒测试和黑盒测试的要素,考虑了用户端、特定的系统知识和操作环境,在系统组件的协同性环境中评价应用软件的设计。

2.2.静态测试

​ 静态测试指被测试程序不在机器上运行,而是采用人工检测和计算机辅助静态分析的手段对程序进行检测。静态分析中进行人工测试的主要方法有桌前检查(Desk Checking)、代码审查和代码走查。经验表明:使用这种方法能够有效地发现30%~70%的逻辑设计和编码错误。

桌前检查(Desk Checking)代码审查代码走查
由程序员自己检查自己编写的程序。程序员在程序通过编译之后,进行单元测试设计之前,对源程序代码进行分析、检验,并补充相关的文档代码审查是由若干程序员和测试员组成一个会审小组,通过阅读、讨论和争议,对程序进行静态分析的过程。代码审查分两步:
第一步,小组负责人提前把设计规格说明书、控制流程图、程序文本及有关要求、规范等分发给小组成员,作为评审的依据。小组成员在充分阅读这些材料之后,进入审查的第二步。
第二步,召开程序审查会。在会上,首先由程序员逐句讲解程序的逻辑。在此过程中,程序员或其他小组成员可以提出问题,展开讨论,审查错误是否存在。实践表明,程序员在讲解过程中能发现许多原来自己没有发现的错误,而讨论和争议则促进了问题的暴露。
在会前,应当给会审小组每个成员准备一份常见错误的清单,把以往所有可能发生的常见错误罗列出来,供与会者对照检查,以提高会审的实效。这个常见错误清单也叫做检查表,它把程序中可能发生的各种错误进行分类,对每一类列举出尽可能多的典型错误,然后把它们制成表格,供在会审时使用。这种检查表类似于单元测试中给出的检查表。
代码走查与代码审查基本相同,其过程也分为两步。
第一步,把材料先发给走查小组每个成员,让他们认真研究程序,然后再开会。
第二步,开会的程序与代码审查不同,不是简单地读程序和对照错误检查表进行检查,而是让与会者"充当"计算机。即首先由测试组成员为被测程序准备一批有代表性的测试用例,提交给走查小组。走查小组开会,集体扮演计算机角色,让测试用例沿程序的逻辑运行一遍,随时记录程序的踪迹,供分析和讨论用。
目的是发现程序中的错误。
这种桌前检查,由于程序员熟悉自己的程序和自身的程序设计风格,可以节省很多的检查时间,但应避免主观片面性。

值得说明的是使用静态测试的方法也可以实现白盒测试。例如:使用人工检查代码的方法来检查代码的逻辑问题,也属于白盒测试范畴。

2.3.McCabe复杂度计算

image-20250926160801154

技巧:流程图转结点图时,相交位置补充结点

计算有向图 G 的环路复杂度公式为: V(G)=m-n+2。 做题技巧:最独立闭环数+ 1

说明:其中 V ( G )是有向图 G 中的环路个数, m 是 G 中的有向弧数, n 是 G 中的节点数(注意:两线交点也要算入)。

image-20250926161025293
例题

采用 McCabe 度量法计算下图所示程序的环路复杂性为()

image-20250926161255645

A、1 B、2 C、3 D、4

答案:C,利用技巧“最小环数+1”,即2+1=3

若用白盒测试方法测试以下代码,并满足条件覆盖,则至少需要()个测试用例。采用 McCabe 度量法算出该程序的环路复杂度为()

image-20250926162242303

A、3 B、4 C、5 D、6

A、1 B、2 C、3 D、4

答案:B、D

解析:(1)先画图,发现如果要想3个if的真假值都取到,那最终4个处理结果都要经过,因此至少需要4个测试用例;

image-20250926162539708

(2)看小圈数为3,环路复杂度为3+1=4

image-20250926162751604

3.测试的阶段

根据测试的目的、阶段的不同,可以把测试分为单元测试、集成测试、确认测试、系统测试等种类

3.1单元测试

​ 单元测试又称为模块测试,是针对软件设计的**最小单位(程序模块)**进行正确性检验的测试工作。其目的在于检查每个程序单元能否正确实现详细设计说明中的模块功能、性能、接口和设计约束等要求,发现各模块内部可能存在的各种错误。单元测试需要从程序的内部结构出发设计测试用例,多个模块可以平行地独立进行单元测试。

​ 单元测试根据详细设计说明书,包括模块接口测试、局部数据结构测试、路径测试、错误处理测试和边界测试,单元测试通常由开发人员自己负责。而由于通常程序模块不是单独存在的,因此常常要借助驱动模块(相当于用于测试模拟的主程序)和桩模块(子模块)完成。单元测试的计划通常是在软件详细设计阶段完成的。

3.2.集成测试

​ 集成测试也称为组装测试、联合测试(对于子系统而言,则称为部件测试)。它主要是将已通过单元测试的模块集成在一起,主要测试模块之间的协作性。集成测试计划通常在软件概要设计阶段完成。

​ 从组装策略而言,可以分为一次性组装和增量式组装,增量式组装又包括自顶向下、自底向上、混合式三种,其中混合式组装又称为三明治测试。

(1)自顶向下集成测试是一种构造程序结构的增量实现方法。模块集成的顺序是首先集成主控模块(主程序),然后按照控制层次结构向下进行集成。隶属于(和间接隶属于)主控模块的模块按照深度优先或者广度优先的方式集成到整个结构中去。

(2)自底向上集成测试是从原子模块(比如在程序结构的最低层的模块)开始来进行构造和测试的,跟自顶向下集成测试相反。

(3)**三明治式测试(混合式组装)**是一种组合的折中测试策略,从"两头"往"中间"测试,其在程序结构的高层使用自顶向下策略,而在下面的较低层中使用自底向上策略,类似于"两片面包间夹馅的三明治"而得名。

​ 软件集成的过程是一个持续的过程,会形成多个临时版本。在不断的集成过程中,功能集成的稳定性是真正的挑战。在每个版本提交时,都需要进行冒烟测试,即对程序主要功能进行验证。冒烟测试也称为版本验证测试或提交测试。

3.3.确认测试

确认测试也称为有效性测试,主要验证软件的功能、性能及其他特性是否与用户要求(需求)一致。确认测试计划通常在需求分析阶段完成。根据用户的参与程度,通常包括4种类型:

(1)内部确认测试:主要由软件开发组织内部按软件需求说明书进行测试。

(2)a测试(Alpha测试):由用户在开发环境下进行测试。

(3)b测试(Beta测试):由用户在实际使用环境下进行测试。

(4)验收测试:针对软件需求说明书,在交付前由用户为主进行的测试

3.4.系统测试

​ 如果项目不只包含软件,还有硬件和网络等,则要将软件与外部支持的硬件、外设、支持软件、数据等其他系统元素结合在一起,在实际运行环境下,对计算机系统的一系列集成与确认测试。一般地,系统测试的主要内容包括功能测试、健壮性测试、性能测试、用户界面测试、安全性测试、安装与反安装测试等。系统测试计划通常是在系统分析阶段(需求分析阶段)完成的。

​ 不管是哪个阶段的测试,一旦测试出问题,就要进行修改。修改之后,为了检查这种修改是否会引起其他错误,还要对这个问题进行测试,这种测试称为回归测试或退化测试。

4.性能测试

性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。负载测试和压力测试都属于性能测试,两者可以结合进行,统称为负载压力测试。通过负载测试,确定在各种工作负载下系统的性能,目标是测试当负载逐渐增加时,系统各项性能指标的变化情况。压力测试是通过确定一个系统的瓶颈或者不能接收的性能点,来获得系统能提供的最大服务级别的测试。

4.1.性能测试的目的

性能测试的目的是验证软件系统是否能够达到用户提出的性能指标,同时发现软件系统中存在的性能瓶颈,优化软件,最后起到优化系统的目的。具体来说,包括以下几个方面:

(1)评估系统的能力,测试中得到的负荷和响应时间数据可以被用于验证所计划的模型的能力,并帮助作出决策。

(2)识别体系中的弱点:受控的负荷可以被增加到一个极端的水平,并突破它,从而修复体系的瓶颈或薄弱的地方。

(3)系统调优:重复运行测试,验证调整系统的活动得到了预期的结果,从而改进性能。

(4)检测软件中的问题:长时间的测试执行可导致程序发生由于内存泄露引起的失败,揭示程序中的隐含的问题或冲突。

(5)验证稳定性和可靠性:在一个生产负荷下执行测试一定的时间是评估系统稳定性和可靠性是否满足要求的唯一方法。

4.2.性能测试的类型

性能测试类型包括负载测试,强度测试,容量测试等。

(1)负载测试:

负载测试是一种性能测试,指数据在超负荷环境中运行,程序是否能够承担。

(2)强度测试:

强度测试是一种性能测试,表明在系统资源特别低的情况下软件系统运行情况。

(3)容量测试:

确定系统可处理同时在线的最大用户数

4.3.负载压力测试

系统的负载压力测试(负载测试)是指系统在某种指定软件、硬件及网络环境下承受的流量,例如:并发用户数、持续运行时间、数据量等,其中并发用户数是负载压力的重要体现。系统在应用环境下主要承受并发访问用户数、无故障稳定运行时间、大数据量操作等负载压力。

负载压力测试的目的如下:

(1)在真实环境下检测系统性能,评估系统性能是否可以满足系统的性能设计要求。

(2)预见系统负载压力承受力,对系统的预期性能进行评估。

(3)进行系统瓶颈分析、优化系统。

在网络应用系统中,负载压力测试应重点关注客户端、网络、服务器(包括应用服务器和数据库服务器)的性能。应获取的关键测试指标如下:

(1)客户端:并发用户数、响应时间、交易通过率以及吞吐量等。

(2)网络:带宽利用率、网络负载、延迟以及网络传输和应用错误等。

(3)服务器:操作系统的CPU占用率、内存使用、硬盘I/O等;

数据库服务器的会话执行情况、SQL执行情况、资源争用以及死锁等;应用服务器的并发连接数、请求响应时间等。

5.面向对象测试基础

面向对象测试是与采用面向对象开发相对应的测试技术,它通常包括4个测试层次,从低到高排列分别是算法层、类层、模板层和系统层。

(1)算法层:测试类中定义的每个方法,基本上相当于传统软件测试中的单元测试。

(2)类层:测试封装在同一个类中的所有方法与属性之间的相互作用。在面向对象软件中类是基本模块,因此可以认为这是面向对象测试中所特有的模块(单元)测试。

(3)模板层:也称为主题层,测试一组协同工作的类或对象之间的相互作用。大体上相当于传统软件测试中的子系统测试,但是也有面向对象软件的特点(例如:对象之间通过发送消息相互作用)。

(4)系统层。把各个子系统组装成完整的面向对象软件系统,在组装过程中同时进行测试。

​ 设计测试方案的传统技术,例如:逻辑覆盖、等价划分、边界值分析和错误推测等方法,仍然可以作为测试类中每个方法的主要技术。面向对象测试的主要目标,也是用尽可能低的测试成本和尽可能少的测试方案,发现尽可能多的错误。但是,面向对象程序中特有的封装、继承和多态等机制,也给面向对象测试带来一些新特点,增加了测试和调试的难度

三,软件维护

image-20250926163402467

​ 在软件维护阶段,主要考查软件维护的分类、软件的可维护性等。

​ 软件经过测试,交付给用户后,在使用和运行过程中可能在软件运行/维护阶段对软件产品进行的修改就是维护。

​ 软件可维护性是指纠正软件系统出现的错误和缺陷,以及为满足新的要求进行修改、扩充和压缩的容易程度。目前广泛用来衡量程序可维护性的因素包括可理解性、可测试性、可修改性。

​ 软件维护占整个软件生命周期的60%-80%,维护的类型主要有3种:

(1)改正性维护(bug):为了识别和纠正软件错误(bug)、改正软件性能上的缺陷、排除实施中的误使用,应当进行的诊断和改正错误的过程就叫做改正性维护。

(2)适应性维护(除用户外的第三方):在使用过程中,外部环境(新的硬、软件配置)、数据环境(数据库、数据格式、数据输入/输出方式、数据存储介质)可能发生变化。为使软件适应这种变化,而去修改软件的过程就叫做适应性维护。

(3)完善性维护(用户角度):在软件的使用过程中,用户往往会对软件提出新的功能与性能要求。为了满足这些要求,需要修改或再开发软件,以扩充软件功能、增强软件性能、改进加工效率、提高软件的可维护性。这种情况下进行的维护活动叫做完善性维护

(4)预防性维护(提前对程序预防升级)

四、软件质量保证

image-20250926165346507
image-20251107114744258

注意:易理解性已经改到易用性中!