1991 年海湾战争中,美军使用“爱国者”导弹拦截伊拉克“飞毛腿”导弹,出现过几次拦截失败事件,后经查明是因为软件计时系统的累积误差所致,该软件缺陷是一个很小的系统时钟错误积累起来造成十几个小时的延迟,致使跟踪系统准确度丧失,最终导致严重的后果。事实上,软件系统的可靠性是很难保证的,几乎没有不存在错误或缺陷的软件系统。这是因为,软件错误或软件缺陷是软件产品的固有成分,是软件“与生俱来”的特性。
在需求分析和设计过程中,需求规格说明在某种程度上与用户要求不符,或者设计中存在一些错误;在写完程序进行编译时会出现语法错误、拼写错误或程序语句错误;软件完成后,应有的功能不能使用;软件在交付使用后,出现一些在测试时没有发现的问题,造成软件故障等。所有这些都可以称为软件缺陷。
软件缺陷包括检测缺陷和残留缺陷。检测缺陷是指软件在用户使用之前被检测出的缺陷;残留缺陷是指软件发布后存在的缺陷,包括在用户安装前未被检测出的缺陷以及检测出但未被修复的缺陷。用户使用软件时,因残留缺陷引起的软件失效症状称为软件故障。
软件缺陷,简单地说,就是存在于软件(文档、数据、程序)之中的那些不希望或不可接受的偏差,即软件质量问题。
软件缺陷会为系统带来一系列的风险,试想:如果软件的某些代码产生了错误,会导致什么样的结果?未被验证的数据交换如果被接受,又会带来怎样的结果?如果文件的完整性被破坏,那么是否还能保证系统符合用户的要求?软件是否还能如期按要求交付使用?当系统发生严重故障时,如果不能保证系统被安全恢复(恢复成被备份的状态),那么系统将会完全崩溃;因某种需求,要暂停系统的运行,而系统又没有办法停止,带来的后果可想而知;进行维护时,系统性能下降到不能接受的水平,从而使用户的需求不能得到满足,甚至因此带来严重的影响;系统的安全性是否有保证,尤其是对于一些特殊的系统,若安全性得不到保障,则可以说是不合格的;系统的操作流程是否符合用户的组织策略和长远规划;若系统的运行不可靠、不稳定,相信用户也不会满意;系统是否易于使用;系统是否便于维护;每一个系统都不是封闭、完全独立的,若系统不能与其他系统相连或者很难与其他系统相连,都是不合格的产品。其中的任何一点都会造成软件开发的失败,例如软件不能正常使用,引起灾难性事件,等等。
从软件缺陷的定义中,可以知道判断缺陷的唯一标准就是看其是否符合用户的需求。在大型软件开发过程中,会出现成千上万甚至更多软件缺陷,要确定这些缺陷怎样描述、分类和跟踪或监控,以确保每个被发现的缺陷都能够及时得到处理。
在运行良好的组织中,缺陷数据的收集和分析是很重要的,从缺陷数据中可以得到很多与软件质量相关的数据。
对缺陷进行跟踪、监控或管理的基本流程是:首先要准确地描述缺陷,然后对各种缺陷进行分类。在此过程中,通过对缺陷进行分类,可以迅速找出哪一类缺陷的问题最大,集中精力预防和排除这一类缺陷,并在这几类缺陷得到控制的基础上,再进一步找到新的容易引起问题的其他几类缺陷。
对软件缺陷进行有效描述涉及如下内容:
①可追踪信息。
缺陷ID(唯一的缺陷ID,可以根据该ID追踪缺陷)。
②缺陷的基本信息。
缺陷的基本信息有如下几部分内容:
缺陷标题、缺陷的严重程度(分为致命、严重、一般、建议)、缺陷的紧急程度、缺陷提交人、缺陷提交的时间、缺陷所属项目/模块、缺陷指定的解决人、缺陷指定的解决时间、缺陷处理人、缺陷处理结果描述、缺陷处理时间、缺陷验证人、缺陷验证结果描述、缺陷验证时间。
③缺陷的详细描述。
对缺陷描述的详细程度直接影响开发人员对缺陷的修改,描述应该尽可能详细。
④测试环境说明。
⑤必要的附件。
⑥从统计的角度出发。
从统计的角度出发,还可以添加“缺陷引入阶段”“缺陷修正工作量”等条目。
软件缺陷的产生主要是由软件产品的特点和开发过程决定的,比如需求不清晰、需求频繁变更、开发人员水平有限等。归结起来,软件缺陷产生的原因主要有以下几点:
(1)需求不明确
软件需求不清晰或者开发人员对需求理解不明确,导致软件在设计时偏离客户的需求目标,造成软件功能或特征上的缺陷。在开发过程中,客户频繁变更需求也会影响软件最终的质量。
(2)软件结构复杂
如果软件系统结构比较复杂,很难设计出一个具有很好层次结构或组件结构的框架,这就会导致软件在开发、扩充、系统维护上的困难。即使能够设计出一个很好的框架,复杂的系统在实现时也会隐藏着相互作用的难题,而导致隐藏的软件缺陷。
(3)编码问题
在软件开发过程中,程序员水平参差不齐,再加上开发过程中缺乏有效的沟通和监督,问题越来越多,如果不能逐一解决这些问题,会导致最终软件中存在很多缺陷。
(4)项目期限短
现在大部分软件产品开发周期都很短,开发团队要在有限的时间内完成软件产品的开发,压力非常大,因此开发人员往往是在疲劳、压力大、受到干扰的状态下开发软件,这样的状态下,开发人员对待软件问题的态度是“不严重就不解决”。
(5)使用新技术
现代社会,每种技术发展都日新月异。使用新技术进行软件开发时,如果新技术本身存在不足或开发人员对新技术掌握不精,也会影响软件产品的开发过程,导致软件存在缺陷。
对软件缺陷进行分类,分析产生各类缺陷的软件过程原因,总结在软件开发过程中不同软件缺陷出现的频度,制定对应的软件过程管理与技术两方面的改进措施,是提高软件组织的生产能力和软件质量的重要手段。
软件缺陷有很多,从不同的角度可以将软件缺陷分为不同的种类。
按照测试种类,可以将软件缺陷分为界面类、功能类、安全性类、兼容性类等。
缺陷的严重程度,可以分为严重、一般、次要、建议。
缺陷的优先级,可以分为立即解决、高优先级、正常排队、低优先级。
缺陷的发生阶段,可以分为需求阶段、构架阶段、设计阶段、编码阶段、测试阶段。
按照不同标准将软件缺陷划分成不同的种类,见表 1.1。
表 1.1 按照不同标准划分缺陷类型
为了正确、全面地描述软件缺陷,首先需要了解缺陷的一些主要属性,这些属性为缺陷修复和缺陷统计分析提供了重要依据。软件缺陷包括以下一些主要属性。
唯一标识软件缺陷的符号,通常用数字编号表示。当使用缺陷管理系统时,由软件自动生成。
根据软件缺陷的自然属性划分的缺陷类型,见表 1.2。
表 1.2 软件的缺陷类型
上述缺陷类型的划分并没有统一的标准,测试人员一般根据本企业所研发软件的特点定义适当的缺陷类型,以便于有针对性地分配缺陷修复工作和进行缺陷分类统计分析。
不同的软件缺陷对软件质量的影响程度不同。有些小的软件缺陷只影响软件的界面美观性,并不影响软件的正常使用,但是另外一些缺陷可能会对软件功能和性能产生严重影响。缺陷的严重程度是从用户使用的角度评判软件缺陷对软件质量的破坏程度,根据这一评判结果可以更为合理地安排缺陷修复工作,优先将有限的时间、人力资源等用于修复严重程度高的缺陷。缺陷严重程度的划分,见表 1.3。
表 1.3 软件的缺陷严重程度
缺陷优先级代表缺陷必须被修复的紧急程度,具体划分见表 1.4。
表 1.4 软件的缺陷优先级
缺陷的优先级是从开发人员和测试人员的角度出发,以合理安排工作时间和提高工作效率为目标进行设置的,当然也考虑到缺陷的严重等级,但并不是严重等级越高的缺陷就一定被越早处理。例如,某一缺陷并不是很严重,但是可能造成测试工作无法正常进行,那么该缺陷就应当被设置为高优先级,需要尽快得到处理。
缺陷出现的可能性是指某一缺陷发生的频率,例如,是每次执行测试用例时都 100%出现,还是执行 10 次测试用例才偶尔出现一两次。缺陷出现的可能性见表 1.5。
表 1.5 软件缺陷出现的可能性
缺陷的出现概率影响到是否能够方便地重现缺陷,是测试和开发人员非常关注的一项缺陷属性。测试人员报告软件缺陷和开发人员修改缺陷时,都希望能够准确地重现软件缺陷,这样才能够准确定位和分析产生缺陷的原因。但是由于消息驱动、并行计算、分布式等复杂软件系统的不断增加,偶发性的软件缺陷经常出现,给缺陷的发现和排除带来了很大的困难。这就要求软件系统具有详细的运行记录能力,如关键性的系统运行日志和用户使用日志,也要求测试人员更为详尽地记录系统运行环境和用户使用步骤等信息,然后通过跟踪与分析找出偶发缺陷的产生原因。
缺陷状态用于反映跟踪和修复缺陷的进展情况,也反映了缺陷在其生命周期中的不同变化。
缺陷起源是指测试时第一次发现缺陷的阶段,例如以下一些典型阶段:需求阶段、总体设计阶段、详细设计阶段、编码阶段、单元测试阶段、集成测试阶段、系统测试阶段、验收测试阶段、产品试运行阶段、产品发布后用户使用阶段。发现缺陷的阶段越早,越有利于降低改正缺陷的费用。
缺陷来源是指软件缺陷发生的地方。在软件生命周期某一阶段发现的缺陷可能来源于前期阶段出现的错误。缺陷一般来源于以下几个地方:
①需求说明书。需求分析错误或不准确。
②设计方案。设计与需求不一致,设计错误等。
③系统接口。接口参数不匹配等问题。
④数据库。数据库逻辑或物理设计问题。
⑤程序代码。完全由于编码问题造成的一些软件缺陷。
⑥用户手册。造成用户使用问题。
缺陷根源是指造成软件缺陷的根本因素,主要是开发过程、工具、方法等软件工程技术与管理因素以及测试策略等因素,通过缺陷根源分析可以改进软件过程管理水平。
软件缺陷生命周期是指软件缺陷从发现到最终被确认修复的完整过程。在这一过程中,软件缺陷会经历不同的状态。典型的软件缺陷生命周期会经历如下状态改变:
①提交—打开:测试人员提交发现的软件缺陷,开发人员确认后准备修复。
②打开—修复:开发人员修复缺陷后通知测试人员进行修复结果验证。
③验证—重新打开:测试人员执行回归测试,验证测试结果后认为缺陷没有完全被修复,再次打开缺陷等待开发人员重新进一步修复。
④验证—关闭:测试人员执行回归测试,确认缺陷已经得到修复,然后将缺陷状态设为最后的关闭状态。