1.1 软件测试与缺陷

1.1.1 软件测试的定义

首先测试(test)是一种活动,测试活动也出现在生活的方方面面,例如工厂的产品投入市场之前需要进行检验,建筑竣工之前需要进行验收,药品投放市场之前需要国家权威部门予以认证等等。软件产品作为一种人们日常使用产品也要在使用之前进行测试,确保质量合格,符合人们的要求。

软件测试则是在软件工程的软件产品开发过程中的一项活动,是一项可以保证软件产品质量的重要活动之一。目前人们对软件测试提出了不同的定义。

IEEE 829-2008定义: 使用人工或自动的手段来运行或测定某个系统的过程,其目的在于检验它是否满足规定的需求或是弄清预期结果与实际结果之间的差别。

IEEE(电气和电子工程师协会):是一个美国的电子技术与信息科学工程师的协会,是世界上最大的非营利性专业技术学会,其会员人数超过40万人,遍布160多个国家。IEEE致力于电气、电子、计算机工程和与科学有关的领域的开发和研究,在航空航天、信息技术、电力及消费性电子产品等领域已制定了900多个行业标准,现已发展成为具有较大影响力的国际学术组织。

维基百科定义: 在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。

ISTQB定义: 包括了所有生命周期活动的过程,包括静态测试和动态测试。它涉及计划、准备和对软件及相关工作产品的评估,以发现缺陷来判定软件或软件的工作产品是否满足特定需求,证明他们是否满足目标。

ISTQB(International Software Testing Qualifications Board):国际软件测试资质认证委员会是国际权威的软件测试资质认证机构,主要负责制订和推广国际通用资质认证框架,即”国际软件测试资质认证委员会推广的软件测试工程师认证”( ISTQB Certified Tester ) 项目。


软件测试的核心思想

在最短的时间内找到最多错误

软件测试要求测试人员尽量缩短查找错误的时间,需要高效而快速的完成测试,高效要求软件测试的数据需要最优化,为加快测试的速度人们常利用工具进行自动化测试;找到最多的错误,是要求测试尽量无遗漏,尽早测试。


软件测试概念的发展——正反两种思维之争

正向思维(Bill Hetzel博士)

  • 定义:软件测试就是为程序或系统能够按预期设想运行而建立足够信心的过程
  • 观点:测试应该是验证软件的正确性

反向思维(Glenford J. Myers博士)

  • 定义:测试是为了发现错误而执行程序的过程
  • 观点:软件测试就是一个过程或一系列过程,用来确认计算机代码完成了其应该完成的功能,不执行其不该有的操作

现代测试思维

现在的软件测试思维是二者的结合,也就是充分结合正向的验证软件正确性,符合约定需求的约束,也要通过反向的思维,尽可能通过测试发现软件存在的问题。


1.1.2 软件缺陷概述

软件缺陷真的很重要吗?是的,就像是一个人生了病,可能这个病能痊愈,有的人也可能会因为一个感冒而丢了性命。人类生产的物品也是如此,总是存在不完美,人类社会总是在不断的改进与进步中。软件测试就是发现软件中的不完美,我们称之为”缺陷”(BUG)。

一、软件缺陷的案例

第一个缺陷的小故事

故事发生在1947年9月9日,一个炎热的下午。当时的机房是一间第一次世界大战时建造的老建筑,没有空调,所有窗户都敞开着。**Grace Hopper(格蕾丝·霍波)**正领导着一个研究小组夜以继日地工作,研制一台称为”MARK II”的计算机,它使用了大量的继电器(电子机械装置,那时还没有使用晶体管),一台不是纯粹的电子计算机。突然,MARK II死机了……

后来发现由于天气炎热加上机房无空调设备,致使大量飞蛾在机房中乱飞,这些飞蛾飞到正要闭合的继电器触点之间被继电器触电夹住,导致电路中断,造成工作故障。只需要将飞蛾找出拿掉,就可以正常工作,Grace Hopper将这只飞蛾拿出来夹在笔记本中,并记录下来,因为飞蛾的英文是bug,所以后来人们就把软件的缺陷称为bug,工作人员又创出了debug单词表示排除计算机故障。

:马克-Ⅱ型计算机在运算的时候,通过继电器开关来执行二进制指令语句,当指令是”1”时,继电器的电磁铁受到激励,带电,使得继电器的接点闭合、接通,电流通过;当指令是”0”时,继电器的电磁铁不受激励,继电器中的弹簧使得接点断开,电流不能通过。

现代软件缺陷案例

年份事件损失
1993Intel奔腾CPU出现浮点计算问题召回所有发售的CPU,造成4亿多美元损失
1996Ariane 5型运载火箭首航失败火箭发射39秒后偏轨,损失3.7亿美元
1999火星探测器坠毁工程成本耗费3.27亿美元
2012骑士资本(KCG)交易系统故障税前4.4亿美元损失,股票下跌32%
2013光大证券公司套利系统缺陷遭证监会重罚5.23亿元
2017亚马逊云S3宕机5个小时的宕机
2017GitLab.com数据库事故丢失6个小时的数据

经典案例:海湾战争爱国者导弹防御系统失败

1991年2月的第一次海湾战争中,一枚伊拉克发射的飞毛腿导弹准确击中美国在沙地阿拉伯的宰赫兰基地,当场炸死28个美国士兵,炸伤100多人,造成美军海湾战争中唯一一次伤亡超过百人的损失。

原因分析

  • 爱国者反导弹系统已经连续工作了100个小时
  • 每工作一个小时,系统内的时钟会有一个微小的毫秒级延迟
  • 爱国者反导弹系统的时钟寄存器设计为24位,因而时间的精度也只限于24位的精度
  • 在工作了100小时后,系统时间的延迟是三分之一秒(0.33秒)
  • 飞毛腿导弹空速达4.2马赫(每秒1.5公里),0.33秒相当于大约600米的误差
  • 雷达在空中发现了导弹,但由于时钟误差没有能够准确地跟踪它,因此基地的反导弹并没有发射

二、软件缺陷的定义

IEEE国际标准729给出了软件缺陷的定义——软件缺陷就是软件产品中所存在的问题,最终表现为用户所需要的功能没有完全实现,不能满足或不能全部满足用户的需求。

从内部看,软件缺陷是软件产品开发或维护过程中所存在的错误、毛病等各种问题;从外部看,软件缺陷是系统所需要实现的某种功能的失效或违背。

软件缺陷的5条准确定义

以计算器为例说明:

  1. 软件未实现产品说明书要求的功能

    • 例如:计算器按下”+“键,结果什么反应也没有;或者得到错误答案
  2. 软件出现了产品说明书指明不会出现的错误

    • 例如:产品说明书声称不会出现死机、闪退等现象,但如果出现这些现象
  3. 软件超出实现了产品说明书提到的功能

    • 例如:计算器除了加、减、乘、除之外还可以求平方根,说明书中从没提到这一功能
  4. 软件实现了产品说明书虽未明确指出但应该实现的目标

    • 例如:电池没电会导致计算不正确,但产品说明书未指出这个问题
  5. 软件测试员发现某些地方不对劲

    • 例如:”=“键布置的位置使其极其不好按;或在明亮光下显示屏难以看清

三、缺陷的来源和类型

缺陷的来源

软件缺陷的产生,首先是不可避免的。其次我们可以从软件本身,团队工作和技术问题等多个方面分析,比较容易确定造成软件缺陷的原因。

1. 软件开发过程自身的特点造成的问题

  • 系统结构不合理造成系统性能问题
  • 接口参数不匹配的问题
  • 语法错误、算法错误、计算和精度问题
  • 数据考虑不周全引起强度或负载问题
  • 对边界考虑不够周全,漏掉某几个边界条件造成的错误
  • 对一些实时应用系统,保证精确的时间同步,否则容易引起时间上不协调、不一致性带来的问题
  • 没有考虑系统崩溃后在系统安全性、可靠性的隐患
  • 等等

2. 软件项目管理的问题

  • 系统分析时,对客户的需求不是十分清楚,或者和用户的沟通存在一些困难
  • 项目需求没有被很好地理解
  • 计划不周,最终导致进度拖延
  • 没有充分的文档资料
  • 软件可靠性缺少度量的标准,质量无法保证
  • 软件难以维护、不易升级
  • 等等

3. 团队合作的问题

  • 不同阶段的开发人员相互理解不一致
  • 软件设计对需求分析结果的理解偏差
  • 编程人员对系统设计规格说明书中某些内容重视不够,或存在着误解
  • 人与人的交流比写程序困难得多
  • 设计或编程上的一些假定或依赖性,没有得到充分的沟通
  • 文档错误、内容不正确或拼写错误
  • 等等

重要发现:软件缺陷是由很多原因造成的,如果把它们按需求分析结果——规格说明书,系统设计结果,编程的代码等归类起来,比较后发现,规格说明书是软件缺陷出现最多的地方

常见的软件缺陷的主要类型

类型描述
需求覆盖问题功能、特性没有实现或部分实现
体系设计或架构设计问题设计不合理,存在缺陷
与需求不符实际结果和预期结果不一致
执行问题运行出错,包括运行中断、系统崩溃、界面混乱
数据问题数据结果不正确、精度不够
非功能性问题如兼容性、并发问题、可靠性问题等

四、软件缺陷的级别

软件的缺陷根据其问题的严重性分为不同的级别。不同的软件公司对缺陷严重性级别的定义不尽相同,但一般可以概括为4种级别:

级别描述
致命的致命的错误,造成系统或应用程序崩溃、死机、系统悬挂,或造成数据丢失、主要功能完全丧失等
严重的严重错误,指功能或特性没有实现,主要功能部分丧失,次要功能完全丧失,或致命的错误声明
一般的不太严重的错误,这样的软件缺陷虽然不影响系统的基本使用,但没有很好地实现功能,没有达到预期效果。如次要功能丧失,提示信息不太准确,或用户界面差,操作时间长等
微小的一些小问题,对功能几乎没有影响,产品及属性仍可使用,如有个别错别字、文字排列不整齐等

除了这4种之外,有时需要”建议”级别来处理测试人员所提出的建议或质疑。


五、软件缺陷与修复代价的关系

在真正的程序测试之前,通过审查、评审会可以发现更多的缺陷。

规格说明书的缺陷会在需求分析审查、设计、编码、测试等过程中会逐步发现,而不能在需求分析一个阶段发现。

缺陷发现越迟代价越大

  • 缺陷发现越早,修复代价越小
  • 很多后期的缺陷大多原因来自前期的需求和设计阶段
  • 缺陷发现越迟,影响范围越广,返工的工作量越大,造成的危害也越大
  • 到了发布阶段软件的修复成本达到了最高点

1.1.3 软件测试的目的和原则

软件测试的目标

直接目标

就是为了更快更早地将软件产品或软件系统中所存在的问题找出来,以促进系统分析人员、设计人员和程序员尽快地解决这些问题。

间接目标

软件测试的间接目标是验证了所有功能已按照事先设计或定义而实现。但其直接目的并非验证每个功能都能实现,而是设法找到每个功能不能正常实现的地方,即尽量促使软件故障的产生。

基于不同立场的测试目的

立场目的
用户角度普遍希望通过软件测试暴露软件中隐藏的错误和缺陷,以考虑是否可以接受该产品
开发者角度则希望成为表明软件产品中不存在错误的过程,验证该软件已正确地实现了用户的要求,确立人们对软件质量的信心

软件测试的主要目的

  1. 验证软件需求和功能是否得到完整实现

    • 一般来说正常情况和非正常情况都要进行测试,看是否得到期望的要求
  2. 验证软件是否可以发布使用

    • 软件是否可以发布要经过测试来验证,未经过测试的软件是不能发布的
  3. 发现软件系统的缺陷、错误以及不足

    • 手段有评审、检视、走读、单元测试、集成测试、系统测试等等
  4. 获取软件产品的质量信息

    • 经过测试,可以推测出软件潜在的缺陷数
  5. 预防下一版本可能出现的问题

  6. 预防用户使用软件时可能出现的问题

  7. 提前发现开发过程中的问题和风险

    • 例如,金字塔原则等
  8. 提供可以使用以分析的测试结果数据

软件测试的目的(简化版)

  1. 测试是程序的执行过程,目的在于发现错误,不能证明程序的正确性,仅限于处理有限种的情况
  2. 检查系统是否满足需求,这也是测试的期望目标
  3. 一个好的测试用例在于发现还未曾发现的错误;成功的测试是发现了错误的测试

软件测试的目标(总结)

以最少的时间和人力找出软件中潜在的各种错误和缺陷。如果成功地实施了测试,就能够发现软件中的错误。


软件测试的原则

原则1:尽早地和不断地进行软件测试

坚持在软件开发的各个阶段的技术评审,这样才能在开发过程中尽早发现和预防错误,把出现的错误克服在早期,杜绝某些隐患,提高软件质量。

原则2:成功的测试需要仔细定义输入输出的期望值

如果对测试输入数据没有给出预期的程序输出结果,那么就缺少了检验实测结果的基准,就有可能把一个似是而非的错误结果当成正确结果。

原则3:程序员或组织应避免检查自己的程序

如果由别人来测试程序员编写的程序,可能会更客观,更有效,并更容易取得成功。

原则4:测试是基于风险的

任何软件或系统哪怕是很小的程序,完全测试是不可能的,例如案例1的三角形的判断程序,仅仅所有的整数的输入就是一个庞大的输入集。测试本质上是基于风险的,好的测试用例能够对未发现的错误高度敏感