软件工程——软件测试

知识来源DUT软件工程课

软件测试概念

定义:

测试是为了发现程序中的错误而执行程序的过程。

目的:

(1) 测试是程序的执行过程,目的在于发现错误
(2) 一个好的测试用例在于能发现至今未发现的错误;
(3) 一个成功的测试是发现了至今未发现的错误的测试。
注:测试永远不能证明程序是正确的。

原则;
  1. 应当把“尽早地和不断地进行软件测试”作为软件开发者的座右铭。
  2. 测试用例应由测试输入数据和对应的预期输出结果这两部分组成。
  3. 程序员应避免测试自己的程序,程序设计组织应避免测试自己的程序。
  4. 在设计测试用例时,应包括合理的输入条件和不合理的输入条件。
  5. 充分注意测试中的群集现象。经验表明,测试后程序中残存的错误数目与该程序中已发现的错误数目成正比。往往80%的错误仅与20%的模块有关。
  6. 严格执行测试计划,排除测试的随意性。
  7. 应当对每一个测试结果做全面检查。
  8. 妥善保存测试计划,测试用例,出错统计和最终分析报告,为维护提供方便。因为在改正错误后或维护后要进行回归测试(regression testing,即全部或部分地重复已做过的测试)。
  9. 检查程序是否做了应做的事仅是成功的一半,另一半是检查程序是否做了不该做的事。
  10. 在规划测试时不要设想程序中不会查出错误。
对象

程序和文档都应成为测试的内容
软件测试并不等于程序测试。软件测试应贯穿于软件定义与开发的整个期间。
需求分析、概要设计、详细设计以及程序编码等各阶段所得到的文档,包括需求规格说明、概要设计规格说明、详细设计规格说明以及源程序,都应成为软件测试的对象。

两种常用的测试方法

黑盒测试,白盒测试
白盒测试又称为结构测试,知道里面是什么样的。
黑盒测试又叫做功能测试,不知道里面是什么样的。
黑盒测试从产品的功能角度进行测试,但是无法进行充分性的测试,可以说是一种确认技术(我们在构造一个正确的系统吗?)
白盒测试通常只用于单元测试,工作量比较庞大,不易生成测试数据。可以说是一种验证技术(我们在正确的构造一个系统吗?)

软件测试的步骤

单元测试(unit testing)
也称模块测试,一般在编码阶段进行
测试对象:模块(功能和内部逻辑)
测试方法:白盒
发现的错误:编码、详细设计
集成测试(integration testing)
根据程序结构图将模块集成为程序进行测试,主要测试模块间的接口和通信
测试方法:黑盒
发现的错误:概要设计
确认测试(validation testing)
根据需求规格说明,检查软件的功能及其它特征是否与用户的需求一致
测试方法:黑盒
发现的错误:需求分析
系统测试(system testing)
将软件、硬件、数据库等集成为计算机系统,检查系统的功能、性能等是否符合计算机系统的要求
测试方法:黑盒
发现的错误:系统工程
对应关系

软件测试用例设计(重点)

白盒测试的测试用例设计

逻辑覆盖

例:对下列子程序进行测试

procedure example(y,z:real;var x:real);
begin
if (y>1) and (z=0) then x:=x/y;
if (y=2) or (x>1) then x:=x+1;
end;
该子程序接受x、y、z的值,并将计算结果x的值返回给调用程序。
在这里插入图片描述
该子程序有两个判定:
a: (y>1) and (z=0)
c: (y=2) or (x>1)
判定a中有两个判定条件:
y>1、 z=0
判定c中有两个判定条件:
y=2 、“x>1”
该子程序有四条可执行路径:
L1 ( sabcde , a为“t”且c为“t”)
L2 ( sace , a为“f”且c为“f”)
L3 ( sacde , a为“f”且c为“t”)
L4 ( sabce , a为“t”且c为“f”)

语句覆盖

语句覆盖是指选择足够的测试用例,使得运行这些测试用例时,被测程序的每个可执行语句都至少执行一次
欲使每个语句都执行一次,只需执行路径L1(sabcde)即可。
测试用例如下:
在这里插入图片描述

判定覆盖(重点)

判定覆盖将每个判定的所有可能结果都至少执行一次,所以,程序中的所有语句也必定都至少执行一次。因此,满足判定覆盖标准的测试用例也一定满足语句覆盖标准。
所有T,F组合都要测试真假假真。。。。
在这里插入图片描述

注意要满足最少的测试用例
如TF,FT两组就将两个判定语句的TF都测试过了。
与此相同FF,TT也可,TT,FF也可,FT,TF也可。

条件覆盖(重点)

每个判定中的每个条件都要走一次
在这里插入图片描述
看覆盖的条件已经全部覆盖了条件语句。

判定/条件覆盖(重点)

是指选择足够的测试用例,使得运行这些测试用例时,被测程序的每个判定的所有可能结果都至少执行一次,并且,每个判定中的每个条件的所有可能结果都至少出现一次
显然,满足判定/条件覆盖标准的测试用例一定也满足判定覆盖、条件覆盖、语句覆盖标准。

在这里插入图片描述

条件组合覆盖(复杂)

条件组合覆盖是指选择足够的测试用例,使得运行这些测试用例时,被测程序的每个判定中条件结果的所有可能组合都至少出现一次
显然,满足条件组合覆盖标准的测试用例一定也满足判定覆盖、条件覆盖、判定/条件覆盖、语句覆盖标准。

路径覆盖(可能要求同时满足)

路径覆盖实际上考虑了程序中各种判定结果的所有可能组合,但它未必能覆盖判定中条件结果的各种可能情况。因此,它是一种比较强的覆盖标准,但不能替代条件覆盖和条件组合覆盖标准。

在这里插入图片描述

黑盒测试技术

黑盒测试主要测试程序是否满足功能、性能等要求。主要诊断以下错误:
不正确或遗漏的功能
接口错误
数据结构或外部数据库访问错误
性能错误
初始化和终止条件错误

黑盒测试主要方法

等价类划分
边界值分析
错误推测法
因果图

等价类划分(重点)

由于不能穷举所有可能的输入数据来进行测试,所以只能选择少量有代表性的输入数据,来揭露尽可能多的程序错误
等价类划分方法把输入数据分为有效输入数据和无效输入数据
有效输入数据指符合规格说明要求的合理的输入数据,主要用来检验程序是否实现了规格说明中的功能
无效输入数据指不符合规格说明要求的不合理或非法的输入数据,主要用来检验程序是否做了规格说明以外的事

等价类划分设计测试用例的步骤

确定等价类
根据程序的功能说明,对每一个输入条件(通常是说明中的一句话或一个短语)确定若干个有效等价类和若干个无效等价类。
在这里插入图片描述
等价类划分
利用等价类设计测试用例的步骤:(1) 为每个有效等价类和无效等价类编号;(2) 设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖的有效等价类,重复这一步,直到所有的有效等价类都被覆盖为止;(3) 为每个无效等价类设计一个新的测试用例。
例:某报表处理系统要求用户输入处理报表的日期,日期限制在2001年1月至2005年12月,即系统只能对该段期间内的报表进行处理,如日期不在此范围内,则显示输入错误息。系统日期规定由年、月的6位数字字符组成,前四位代表年,后两位代表月。如何用等价类划分法设计测试用例, 来测试程序的日期检查功能?
第一步:等价类划分
在这里插入图片描述
第二步:为有效等价类设计测试用例对表中编号为1,2,3的3个有效等价类,用一个测试用例覆盖:

在这里插入图片描述
第三步:为每一个无效等价类设至少计一个测试用例
在这里插入图片描述
注意:无效等价类每一个无效都要写一个,不能重合。456789,10都要有测试用例。
例:考察一个把数字串转变成整数的函数。用二进制补码表示整数,机器字长16位,即整数范围最小为- 32768,最大为32767。函数及参数的PASCAL说明如下:
function StrToInt (dstr : shortstr) : integer;
type shortstr = array [1…6] of char;
要求被处理的数字串是右对齐的,即在少于6个字符的串左边补空格。负号在最高位数字左边一位。
试用等价划分法设计测试方案。
解:首先根据规格说明划分等价类。考虑到PASCAL编译器的固有检错功能,测试时不需要使用长度不等于6的数组,也不需要用非字符数组类型的参数。
有效输入类:
①1~6个数字字符组成的数字串(最高位非0);
②最高位为0的数字串; ③最高位左邻负号的数字串;
无效输入类:
④空字符串(6位空格);⑤左边补位的既非0亦非空格;
⑥最高位右边含有空格;
⑦最高位右边含有其它非数字字符;
⑧负号与最高位间有空格;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

边界值分析(重点)

边界值分析也是一种黑盒测试方法,是对等价类划分方法的补充。
人们从长期的测试工作经验得知,大量的错误是发生在输入或输出范围的边界上,而不是在输入范围的内部。因此针对各种边界情况设计测试用例,其揭露程序中错误的可能性就更大。
(1)边界值分析不是从某等价类中 随便挑一个作为代表,而是使 这个等价类的每个边界都要作为测试条件。
(2)边界值分析不仅考虑输入条件,还要考虑输出空间产生的测试情况
如何确定边界?通常的边界检查原则:
数字:最大/最小/刚大于最大/刚小于最小、
字符串:
位置(首位/末位/首位前/末位后)
长度(零/ 很大/ 超出缓冲区)
取值范围(刚到达边界/ 刚超出边界)
其他如质量、大小、速度、方位、尺寸、空间等都可按照最轻/ 最重,最大/最小,最快/最慢、最高/最低、最短/最长、空/满等确定边界。
使用边界值分析,最重要的是确定正确的边界值域。对于输入/输出等价类,选取正好等于、刚刚大于和刚刚小于边界值的数据作为测试数据。
例如,判断三角形问题,问题的提法是:程序接受 3 个整数 a、b 和 c 作为输入,用做三角形的边。整数 a、b 和 c 必须满足以下条件:
C1.1≤a≤200 C2.1≤b≤200 C3.1≤c≤200 C4.a<b + c
C5.b<a + c C6.c<a + b
按照构成三角形的条件
C1、C2和C3,整数a、b、c的边界值为1和200,稍超出边界的值为0和201。
C4、C5和C6的边界值分别是b+c=a+1、a+c=b+1和b+c=a+1。
可取的测试用例如下表所示。
在这里插入图片描述
在这里插入图片描述
到达边界的值是合理的输入,只要最少的测试数据就可以。
超出边界的值是不合理的输入,必须逐个检测,在检查某一个数据时让其他的数据为边界或边界内合理的值。
分析规格说明,找出其他可能的边界条件。
通常和等价类结合使用。

错误推测法

错误推测方法是一种凭直觉和经验推测程序中可能存在的各种错误,从而针对这些可能存在的错误设计测试用例的方法。
这种方法没有机械的执行步骤,主要依靠直觉和经验。
错误推测法的基本想法是:列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据它们设计测试用例。
例如,测试一个排序子程序,可考虑如下情况:
输入表为空;
输入表只有一个元素;
输入表的所有元素都相同;
输入表已排序。
又如,测试二分法检索子程序,可考虑如下情况:
表中只有一个元素;
表长为2的n次方;
表长为2的n次方-1;
表长为2的n次方+1;

因果图(了解)

边值分析和等价类划分方法都没有考虑输入条件的各种组合,但输入条件组合的数目相当大,因此应该用某种方法来选择输入条件的子集,再考虑它们的组合。因果图就是一种帮助人们系统地选择一组高效测试用例的方法。
因果图方法的特点是:
考虑输入条件的组合关系;
考虑输出条件对输入条件的依赖关系,即因果关系;
测试用例发现错误的效率高;
能检查出功能说明中的某些不一致或遗漏。
例如,有一个处理单价为5角钱的饮料的自动售货机软件。其规格说明如下:
若投入5角钱或1元钱的硬币,押下〖橙汁〗或〖啤酒〗的按钮,则相应的饮料就送出来。若售货机没有零钱找,则一个显示〖零钱找完〗的红灯亮,这时在投入1元硬币并押下按钮后,饮料不送出来,而且1元硬币也退出来;若有零钱找,则显示〖零钱找完〗的红灯灭,在送出饮料的同时退还5角硬币。”
(1) 分析这一段说明,列出原因和结果原因: 1. 售货机有零钱找 2. 投入1元硬币 3. 投入5角硬币4. 押下橙汁按钮5. 押下啤酒按钮
建立中间结点,表示处理中间状态11. 投入1元硬币且押下饮料按钮12. 押下〖橙汁〗或〖啤酒〗的按钮13. 应当找5角零钱并且售货机有零钱找14. 钱已付清
结果: 21. 售货机〖零钱找完〗灯亮
22. 退还1元硬币
23. 退还5角硬币
24. 送出橙汁饮料
25. 送出啤酒饮料(2) 画出因果图。所有原因结点列在左
边,所有结果结点列在右边。
(3) 由于原因 2 与 3 ,4 与 5 不能同时发生,分别加上约束条件E。(4) 根据因果图画出判定表
(5) 根据判定表设计测试用例
在这里插入图片描述
在这里插入图片描述

(这也太复杂了吧orz)

软件测试的策略

测试过程通常按4个步骤进行,即单元测试、集成测试、确认测试和系统测试。

在这里插入图片描述

单元测试

单元测试又称模块测试,是针对软件设计的最小单位 ─ 程序模块,进行检验的测试工作。其目的在于发现各模块内部可能存在的各种差错。通常采用白盒测试。
单元测试需要从程序的内部结构出发设计测试用例。多个模块可以平行地独立进行单元测试。

单元测试的内容

模块接口:保证测试时进出程序单元的信息是正确流动的;
局部数据结构:保证临时存储的数据在算法执行的整个过程中都能维持其完整性;
边界条件:保证模块在极限或严格的情况下仍然能正确执行;
所有独立路径:保证模块中的所有语句都至少执行一次;
所有错误处理路径。

单元测试的步骤

单元测试通常与编码工作结合起来进行
在这里插入图片描述

集成测试

集成测试 也称组装测试、联合测试
经单元测试后,每个模块都能独立工作,但把它们放在一起往往不能正常工作。
主要问题在于:
数据可能在穿越模块接口时丢失;
一个模块可能对另一个模块产生无法预料的副作用;
当子功能被组合起来时,可能不能达到预期的父功能;
单个模块可以接受的不精确性(如误差),连接起来后可能会扩大到无法接受的程度;
全局数据结构可能会存在问题。
集成测试方法
通常采用黑盒测试技术
实施策略:

非渐增式测试(都结合在一起测试)
渐增式测试(一点一点往上加)

在这里插入图片描述

自顶向下结合方式

在这里插入图片描述
(这种是按顺序增加模块)

自底向上结合方式

在这里插入图片描述
在这里插入图片描述

优缺点

自顶向上:可在测试早期实现并验证系统功能,确定是不需要驱动模块需要桩模块
自底向上:设计用例容易,不需要桩模块,缺点是最后才是一个整体。
一般对软件结构的上层使用自顶向下结合的方法;
对下层使用自底向上结合的方法;

回归测试

在集成测试时,每当增加一个新模块时,集成的软件就发生了改变,新的数据流路径被建立,新的I/O操作可能也会出现,还可能激活新的控制逻辑。这些改变可能使原本正常工作的功能产生错误。
在软件维护时,当软件修改后,也可能使原本正常工作的功能产生错误。
回归测试是对某些已经进行过的测试的子集的重新执行,以保证软件的改变不会传播不可预料的副作用或附加的错误。
回归测试集(已经过测试的子集)包括三种不同类型的测试用例:
能测试软件所有功能的代表性测试用例
专门针对可能会被修改影响的软件功能的附加测试
注重于修改过的软件模块的测试

确认测试

确认测试以软件需求规格说明书为依据,检查软件的功能和性能及其它特性是否与用户的需求一致,包括合同规定的全部功能和性能、文档资料(正确且合理)、其它需求(如可移植性、兼容性、错误恢复能力、可维护性等)。
确认测试的结果可分为两类:
满足需求规格说明要求的功能或性能特性,用户可以接受。
发现与需求规格说明不一致的功能或性能特征,须列出提问单。

α测试和β测试

如果软件是为一个客户开发的,那么,最后由客户进行验收( Acceptance Testing )测试,以便客户确认该软件是他所需要的。
如果软件是给许多客户使用的,那么不可能让每个客户做验收测试,大多数软件厂商使用一个称为α测试和测试的过程,来发现那些似乎只有最终用户才能发现的错误。
α测试的目的是评价软件产品的FURPS(即功能、可使用性、可靠性、性能和支持)。尤其注重产品的界面和特色。
α测试是由一个用户在开发者的场所来进行的,软件在开发者对用户的“指导”下进行测试,开发者负责记录错误和使用中出现的问题,所以, α测试是在一个受控的环境中进行的。
β测试是由软件的最终用户在一个或多个用户场所来进行的,开发者通常不在测试现场,因此β测试是软件在一个开发者不能控制的环境中的“活的” 应用。用户记录下所有在β测试中遇到的(真正的或是想象中的)问题,并定期把这些问题报告给开发者,在接到β测试的问题报告后,开发者对系统进行最后的修改,然后开始准备向所有的用户发布最终的软件产品。
(区别开发者是否在现场,β测试是不受控的)

系统测试

系统测试,是将通过确认测试的软件,作为整个基于计算机系统的一个元素,与其它系统成分(如硬件、外设、某些支持软件、数据和人员等)集成起来,在实际运行环境下,对计算机系统进行一系列的集成测试和确认测试。
在这里插入图片描述

恢复测试:

恢复测试是通过各种手段,强制软件发生故障,然后来验证系统能否在指定的时间间隔内恢复正常,包括修正错误并重新启动系统。
如果恢复是由系统自身来完成的,那么,需验证重新初始化、检查点机制、数据恢复和重启动等的正确性。
如果恢复需要人工干预,那么要估算平均修复时间MTTR(mean time to repair)是否在用户可以接受的范围内。

安全测试

安全测试用来验证集成在系统中的保护机制能否实际保护系统不受非法侵入。
在安全测试过程中,测试者扮演一个试图攻击系统的角色,采用各种方式攻击系统。例如,截取或码译密码;借助特殊软件攻击系统;“制服”系统,使他人无法访问;故意导致系统失效,企图在系统恢复之机侵入系统;通过浏览非保密数据,从中找出进入系统的钥匙等等。
一般来说,只要有足够的时间和资源,好的完全测试一定能最终侵入系统。系统设计者的任务是把系统设计成:攻破系统所付出的代价大于攻破系统后得到信息的价值。

压力测试

压力测试也称强度测试,它是在一种需要非正常数量、频率或容量的方式下执行系统,其目的是检查系统对非正常情况的承受程度。例如:
当系统的中断频率是每秒1或2个时,执行每秒10个中断的测试用例
将输入数据的数量提高一个数量级来测试输入功能如何响应
执行需要最大内存或其它资源的测试用例
执行可能导致大量磁盘驻留数据的测试用例

性能测试

性能测试用来测试软件在集成的系统中的运行性能。它对实时系统和嵌入式系统尤为重要。
性能测试可以发生在测试过程的所有步骤中
单元测试时,主要测试一个独立模块的性能,如算法的执行速度。
软件集成后,进行软件整体的性能测试。
计算机系统集成后,进行整个计算机系统的性能测试。
性能测试常常需要与压力测试结合起来进行,而且常常需要一些硬件和软件测试设备,以监测系统的运行情况。

测试完成的标准

因为无法判定当前查出的错误是否是最后一个错误,所以决定什么时候停止程序测试就成了最困难的问题,但是测试最后一定要停止的。
几种实用的测试完成标准:
Musa和Ackerman提出了一个基于统计标准的答复:“不,我们不能绝对地认定软件永远也不会再出错,但是相对于一个理论上合理的和在试验中有效的统计模型来说,如果一个在按照概率的方法定义的环境中,1000个CPU小时内不出错运行的概率大于0.995的话,那么我们就有95%的信心说,我们已经进行了足够的测试”。

经验表明,完成软件测试通常要经历三个阶段:
第一阶段:由于目标系统的大部分模块还不能正常运行,系统中存在的错误较多,因此测试用例完成得慢;
第二阶段:完成测试用例的效率很高;
第三阶段:发现的错误往往是较难改正的,因此测试用例完成率明显降低。

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值