13.1 软件可靠性
目前,硬件可靠性测试技术和评估手段日趋成熟,已经得到了业界的认可。
软件可靠性模型的研究多集中在开发阶段、测试阶段、评估阶段的可靠性模型。
13.1.1 软件可靠性的定义
可靠性(Reliability)是指产品在规定的条件下和规定的时间内完成规定功能的能力。
按照产品可靠性的形成,分为固有可靠性、使用可靠性。
固有可靠性是通过设计、制造赋予产品的可靠性。
使用可靠性既受设计、制造的影响,又受使用条件的影响。
软件与硬件从可靠性角度来看,主要有4个不同点:
1、复杂性,软件内部的逻辑高度复杂,硬件则相对简单。
2、物理退化,一个正确的软件任何时刻均可靠,一个正确的硬件、元器件、系统则可能在某个时刻失效。
3、唯一性,软件是唯一的,软件复制不改变软件本身,硬件不可能完全相同,概率方法在硬件可靠性领域取得巨大成功。
4、版本更新快,软件版本更新较快,也给软件可靠性评估带来较大的难度。
1983年,美国IEEE 对“软件可靠性”做出了更明确的定义。
1989年,我国国家标准 GB/T-11457也采用了这个定义。
定义:在规定的条件下,在规定的时间内,软件不引起系统失效的概率。
依然沿用了“产品可靠性”的定义。
1、规定的时间
由于软件运行的环境与程序路径选取的随机性,软件的失效为随机事件,所以运行时间属于随机变量。
2、规定的条件
不同的环境条件下的可靠性是不同的,计算机的配置情况、对输入的要求。
有了明确规定的环境条件,还可以有效地判断软件失效的责任在用户方还是开发放。
3、所要求的功能
软件可靠性还与规定的任务和功能有关。
要准确度量软件系统的可靠性,必须先明确它的任务和功能。
4、“软件可靠性”定义具有如下特点:
1. 用内在的“缺陷” 和 外在的“失效”关系来描述可靠性。
2. 定义使人们对软件可靠性进行量化评估成为可能。
3. 用概率的方法描述可靠性是比较科学的。
13.1.2 软件可靠性的定量描述
软件的可靠性可以基于 使用条件、规定时间、系统输入、系统使用、软件缺陷 等变量构建的数学表达式。
1、规定时间:自然时间、运行时间、执行时间。
使用执行时间来度量软件的可靠性最为准确。
2、失效率:把软件从运行开始,到某一时刻t 为止,出现失效的概率用 F(t)表示。
F(0)=0,即软件运行初始时刻失效概率为0。
F(t)在时间域(0,+无穷大)上是单调递增的。
F(+无穷大)=1,即失效概率在运行时间不断增长时 趋向于1,这也意味着任何软件都存在缺陷。
3、可靠度:在规定的条件下,规定的时间内 不发生失效的概率。
4、失效强度(Failure Intensity)单位时间 软件系统出现失效的概率。
5、失效率(Failure Rate)又称 风险函数(Hazard Function),也可以称为条件失效强度。
就是当软件在 0~t 时刻内 没有发生失效的条件下,t 时刻软件系统的失效强度。
公式略。
6、可靠度与失效率之间的换算。
7、平均失效时间(Mean Time to Failure,MTTF)就是软件运行后,到下一次出现失效的平均时间。更直观地表明一个软件的可靠度。
需要对 软件可靠度 这个反映软件可靠性的肚量指标作下列补充说明:
1. 需指明它与其他软件的界限。
2. 软件失效必须明确定义。
3. 必须假设硬件无故障(失效)和软件有关变量输入正确。
5. 必须指明时间基准:自然时间(日历时间)、运行时间、执行时间(CPU 时间)、其他时间基准。
6. 通常以概率度量,也可以模糊数学中的可能性加以度量。
7. 在时间域上进行,是一种动态度量,也可以是在数据域上,表示成功执行一个回合的概率。
软件回合是软件运行最小的、不可分的执行单位。
8. 有时将软件运行环境简单地理解为软件运行剖面(Operational Profile)。
运行剖面定义了关于软件可靠性描述中的“规定条件”,测试环境、测试数据 等一系列问题。
13.1.3 可靠性目标
使用 失效强度 表示软件缺陷对软件运行的影响程度。
不仅取决于软件失效发生的概率,还和软件失效的严重程度有很大关系。引出另外一个概念——失效严重程度类(Failure Severity Class)。
失效严重程度类 就是对用户具有相同程度影响的失效集合。
对失效严重程度的分级 可以按照不同的标准进行,对成本影响、对系统能力的影响 等。
对成本的影响可能包括失效引起的额外运行成本、修复和恢复成本、现有潜在的业务机会的损失等。
对系统能力的影响常常表现为 关键数据的损失、系统异常退出、系统崩溃、导致用户操作无效等。
可靠性目标是指客户对软件性能满意程度的期望。通常用 可靠度、故障强度、平均失效时间(MTTF)等指标来描述。
建立定量的可靠性指标需要对可靠性、交付时间、成本进行平衡。
13.1.4 可靠性测试的意义
1、软件失效可能造成灾难性的后果。
2、软件的失效在整个计算机系统失效中的比例较高。
80%和软件有关。
结构太复杂了,一个较简单的程序,其所有路径数量可能是一个天文数字。
3、相比硬件可靠性技术,软件可靠性技术很不成熟。
4、软件可靠性问题是造成费用增长的主要原因之一。
5、系统对于软件的依赖性越来越强。
13.1.5 广义的可靠性测试与侠义的可靠性测试
广义的软件可靠性测试是指为了最终评价软件系统的可靠性而运用建模、统计、试验、分析、和评价等一系列手段对软件系统实施的一种测试。
侠义的软件可靠性测试是指为了获取可靠性数据,按预先确定的测试用例,在软件的预期使用环境中,对软件实施的一种测试。
也叫“软件可靠性试验(Software Reliability Test)”,它是面向缺陷的测试,以用户将要使用的方式来测试软件,所获得的测试数据与软件的实际运行数据比较接近。
可靠性测试是对软件产品的可靠性进行调查、分析、评价的一种手段。
对检测出来的失效的分布、原因、后果 进行分析,并给出纠正建议。
总的来说,可靠性测试的目的可归纳为以下三个方面:
1、发现软件系统在 需求、设计、编码、测试、实施 等方面的 各种缺陷。
2、为软件的使用、维护提供可靠性数据。
3、确认软件是否达到可靠性的定量要求。
13.2 软件可靠性建模
13.2.1 影响软件可靠性的因素
软件可靠性模型(Software Reliability Model)是指 为预计或估算软件的可靠性所建立的可靠性框图和数学模型。
模型将复杂系统的可靠性逐级分解为简单系统的可靠性,以便 定量预计、分配、估算、评价复杂系统的可靠性。
影响软件可靠性的主要因素:缺陷的引入、发现、清除。
缺陷的引入主要取决于软件产品的特征和软件的开发过程特性。
缺陷的发现依靠运行剖面。
缺陷的清除依赖于失效的发现、修复活动、可靠性方面的投入。
影响软件可靠性的主要因素如下:
1、运行剖面(环境)。
2、软件规模。
3、软件内部结构。
4、软件的开发方法和开发环境。
5、软件的可靠性投入。人力、资金、资源、时间 等。
早期重视软件可靠性并采取措施开发出来的软件,可靠性有明显的提高。
13.2.2 软件可靠性建模方法
可靠性模型通常由以下几部分组成:
1、模型假设。模型是实际情况的简化或规范化,总要包含若干假设。
2、性能度量。软件可靠性模型的输出量就是性能度量。
3、参数估计方法。
4、数据要求。
绝大多数模型包含三个共同假设:
1、代表性假设。选取代表软件实际的运行剖面。
2、独立性假设。假设认为软件失效是独立发生于不同时刻。
3、相同性假设。认为所有软件失效的后果(等级)相同,即建模过程只考虑软件失效的具体发生时刻,不区分软件的失效严重等级。
如果在进行预测时发现引入了新的错误,或修复行为使新的故障不断发生,就应该停止预测。否则,这样的变化会因为增加问题的复杂程度而使模型的适用性降低。
好的软件可靠性模型应该具有如下重要特性:
1、基于可靠性的假设。
2、简单。
3、计算一些有用的量。
4、给出未来失效行为的好的映射。
5、可广泛使用。
13.2.3 软件的可靠性模型分类
可靠性模型大致可分为如下10类:
1、种子方法模型。
利用捕获一再捕获抽样技术估计程序中的错误数,在程序中预先有意“播种”一些设定错误的“种子”,然后根据测试出的原始错误和发现的诱导错误比例,估计程序中残留的错误数。
优点是简单易行,缺点是诱导错误的“种子”与实际的原始错误之间的类比性估量困难。
2、失效率类模型。
3、曲线拟合类模型。
用回归分析的方法研究软件 复杂性、缺陷数、失效率、失效间隔时间,包括参数方法和非参数方法两种。
4、可靠性增长模型。
5、程序结构分析模型。
通过对每一个节点可靠性、节点间转换的可靠性和网络在节点间的转换概率,得出该持续程序的整体可靠性。
6、输入域分类模型。
7、执行路径分析方法模型。
8、非其次泊松过程模型。
NHPP,以软件测试过程中单位时间的失效次数为独立泊松随机变量,来预测今后软件的某使用时间点的积累失效次数。
9、马儿可夫过程模型。
10、贝叶斯模型。
利用失效率的试验前分布和当前的测试失效信息,来评估软件的可靠性。
当软件可靠性工程师对软件的开发过程有充分的了解,软件的继承性比较好时具有良效果的可靠性分析模型。
时间域。
失效数类:失效数是有限的还是无限的。
失效数分布。
有限类:用时间表示的失效强度的函数形式。
无限类:用经验期望失效数表示的失效强度的函数形式。
13.2.4 软件可靠性模型举例
1、模型假设
JM 模型的基本假设如下:
1. 初始错误个数为一个未知的常数。
2. 发现错误立即被完全排除,并且不引入新的错误,排除时间忽略不记,因此每次排错后就要减 1。
3. 失效率剩余的错误个数成正比。
2、函数表达式。
软件可靠性模型并不成熟,定量分析方法和数学模型要在实践中不断加以验证和修正。
不同类型的软件,应用方式也有很大区别。
13.2.5 软件可靠性测试概述
可靠性测试 由可靠性目标的确定、运行剖面的开发、测试用例的设计、测试实施、测试结果的分析 等主要活动组成。
软件可靠性测试 还必须考虑对软件开发进度和成本的影响,最好是在受控的自动测试环境下,由专业测试机构完成。
13.2.6 定义软件运行剖面
弧 用来连接状态并表示由各种激励导致的转换,将转换概率分配给每个弧。
每类用户都可能以不同的方式使用系统。
两种类型分层形式:用户级分层、用法级分层。
用法级分层依赖于在测试状态下系统能做什么。
用户级分层考虑各种类型的用户,以及他们如何使用系统。
这些概率估计主要是基于如下几个方面:
1、从现有系统收集到的数据。
2、与用户的交谈或对用户进行观察获得的信息。
3、原型使用与测试分析的结果。
4、相关领域专家的意见。
13.2.7 可靠性测试的实施
有必要检查软件需求与文档是否一致,检查软件开发过程中形成的文档的准确性、完整性、一致性。
可靠性测试依赖于软件的可测试性。
为了获得更多的可靠数据,应该使用多态计算机同时运行软件,以增加累计时间。
用时间定义的软件可靠性数据分为4类:
1、失效时间数据。
2、失效间隔时间数据。
3、分组时间内的失效数据。
4、分组时间的累计失效数。
这 4类数据可以相互转化。
测试过程中必须真实地进行记录,每个测试记录必须包含如下信息:
1、测试时间。
2、含有测试用例的测试说明或标识。
3、所有与测试有关的测试结果,包括失效数据。
4、测试人员。
测试活动结束后要编写《软件可靠性测试报告》具备如下内容:
1、软件产品标识。
2、测试环境配置(硬件和软件)。
3、测试依据。
4、测试结果。
5、测试问题。
6、测试时间。
13.3 软件可靠性评价
13.3.1 软件可靠性评价概述
估计软件当前的可靠性,以确认是否可以终止测试并发布软件,还可以预计软件要达到相应的可靠性水平所需要的时间和工作量,确认软件的执行与需求的一致性。
13.3.2 怎样选择可靠性模型
可以从以下几个方面进行比较和选择:
1、模型假设的适用性。
2、预测的能力与质量。
3、模型输出值能否满足可靠性评价需求。
最重要的几个需要精确估计的可靠性定量指标包括如下内容:
1. 当前的可靠度。
2. 平均失效时间。
3. 故障密度。
4. 期望达到规定可靠性目标的日期。
5. 达到规定的可靠性目标的成本要求。
4、模型使用的简便性
简便性一般包含如下三层含义:
1. 模型需要的数据 易于收集,成本不能超过可靠性计划的预算。
2. 模型应该简单易懂,测试人员不会花费太多的时间去研究专业的数学理论。
3. 模型应该便于使用。
13.3.3 可靠性数据的收集
面向缺陷的可靠性测试 产生的测试数据经过分析后,可以得到非常有价值的可靠性数据,这部分数据取决于定义的运行剖面和选取的测试用例集。
可靠性数据的收集工作是贯穿整个软件生命周期的。
可行的一些办法如下:
1、及早确定所采用的可靠性模型。
2、指定可实施性较强的可靠性数据收集计划,指定专人负责,按照统一的规范收集记录可靠性数据。
3、重视软件测试特别是可靠性测试产生的测试数据的整理和分析。
4、充分利用数据库来完成可靠性数据的存储和统计分析。
13.3.4 软件可靠性的评估和预测
1、判断是否达到了可靠性目标。
2、如未能达到,要再投入多少时间、多少人力、多少资金。
3、在软件系统投入实际运行 若干时间后,能否达到交付或部分交付用户使用的可靠性水平。
没有失效就无法估计可靠性。
要在模型之外运行一些统计技术和手段对可靠性数据进行分析,作为可靠性模型的补充、完善、修正。
辅助方法如下:
1、失效数据的图形分析方法。
1. 积累失效个数图形。
2. 单位时间段内的失效数的图形。
3. 失效间隔时间图形。
2、试探性数据分析技术(Exploratory Data Analysis,EDA)对可靠性分析有用的信息如下:
1. 循环相关。
2. 短期内失效数的急剧上升。
3. 失效数集中的时间段。
13.4 软件的可靠性设计与管理
13.4.1 软件可靠性设计
实践证明,保障软件可靠性,最有效、最经济、最重要的手段是 在软件设计阶段采取措施进行可靠性控制。
1、软件可靠性设计是软件设计的一部分,必须在软件的总体设计框架中使用,并且不能与其他设计原则相冲突。
2、软件可靠性设计在满足提高软件质量要求的前提下,以提高和保障软件可靠性为最终目标。
3、软件可靠性设计应确定软件的可靠性目标,不能无限扩大化,排在功能度、用户需求、开发费用之后考虑。
容错设计、检错设计、降低复杂度设计 等技术。
1、容错设计技术
1. 恢复块设计,一旦文本出现故障,用备份文本加以替换。
2. N版本程序设计,对于相同初始条件和相同输入的操作结果,实行多数表决,防止其中某一软件模块/版本的故障提供错误的服务。
必须注意以下两方面:
使软件的需求说明具有完整性和精确性。
设计全过程的不相关性。
3. 冗余设计
在相同的运行环境中,一套软件出故障的地方,另外一套也一定会出现故障。
在一套完整的软件系统之外,设计一种不同路径、不同算法或不同实现方法的模块或系统作为备份。
费用可能接近单个版本软件开发费用的两倍,还有可能导致软件运行时所花费的存储空间、内存消耗、运行时间有所增加,需要在可靠性要求和额外付出代价之间做出折中。
2、检错技术
检错技术实现的代价一般低于容错技术和冗余技术,但它有一个明显的缺点,就是不能自动解决故障。
着重考虑几个要素:检测对象、检测延时、实现方式、处理方式。
3、降低复杂度设计
模块复杂性主要包含模块内部数据流向和程序长度两个方面,结构复杂性用不同模块之间的关联程度表示。
软件复杂性是产生软件缺陷的重要根源。
在设计师就应该考虑降低软件的复杂性,是提高软件可靠性的有效方法。
在保证实现软件功能的基础上,简化软件结构,缩短程序代码长度,优化软件数据流向,降低软件复杂度,从而提高软件可靠性。
13.4.2 软件可靠性管理
为了进一步提高软件可靠性,又提出软件可靠性管理的概念,把软件可靠性活动贯穿于软件开发的全过程。
各个阶段的可靠性活动的目标、计划、进度、任务、修正措施等。
由于软件之间的差异较大,下面的每项活动并不是每一个软件系统的可靠性管理的必须内容,也不是软件可靠性管理的全部内容。