软件测试的基础之名词解析
一、软件质量
1.软件质量的度量方法
软件质量的度量方法有多种,它们可进一步划分为静态质量特性和动态质量特性。
静态质量特性是指实际的代码和相关文档。包括结构化的、可维护的、可测的代码以及正确而又完整的文档。
动态质量特性是指软件在使用中表现出来的行为。包括软件可靠性、正确性、完整性、一致性、易用性和性能。
2.软件的可靠性
定义一:软件可靠性是指软件在给定时间间隔和给定条件下无故障运行的概率(定义中所指的概率依赖于程序输入的分布情况,这种输入分布常常被称作操作剖面。根据定义,软件的可靠性会因操作剖面的不同而不同。)
定义二:软件可靠性是指软件在预期的环境条件下无故障运行的概率(这个定义只与软件功能的正确性相关。由于没有操作剖面的定义,整个输入域被认为是均匀分布的。环境指软件运行所需的硬件和软件要素,包括硬件设备。操作系统以及其他必需的应用程序。)
3.软件的正确性
正确性指一个软件的正确操作,并且通常与一些软件文档相关。它是一个二元度量,其结果是正确或不正确
二、测试与调试
测试是一个判断软件是否如预期那样运行的过程。在测试过程中,可能会发现被测软件当中存在错误。当测试发现了错误,这个确定错误原因以及纠正错误的过程称作调试。测试与调试是两个相关联的活动。
三、测试度量
“度量”反映的是一个测量标准。包括组织级度量、项目级度量、过程级度量和产品级度量。
四、测试与验证
程序验证旨在通过表现程序不含有错误而证明程序的正确性。这与软件测试很不相同。软件测试旨在暴露程序中存在的错误。也就是说,程序验证旨在证明一个程序对所有满足条件的输入都运行正常,而软件测试旨在证明一个程序是可靠的,因为再没有严重的错误被发现了。
五、缺陷管理
缺陷管理包括:缺陷预防、缺陷发现、缺陷记录与报告、缺陷分类、缺陷纠正、缺陷预测等。
目前,存在一些用于记录缺陷、管理缺陷信息的工具,比如开源工具Bugzilla、商用工具FogBugz。
缺陷预防是通过大量的规程和工具来完成的。例如,良好的编码技术、单元测试计划、代码审查都是缺陷预防过程的重要手段。
缺陷发现,就是根据动态测试与静态测试中观察和发现的失效,识别出引起失效的缺陷。在发现缺陷的过程中,常常还包括调试被测试的代码。
缺陷分类:要对已发现的缺陷进行分类,并将记录在一个数据库中。缺陷分类有助于组织机构统计缺陷信息,如缺陷类型、发生频率、在开发周期中的阶段、设计的文档等、这些统计数据随后传递给组织的过程改进小组,由他们进行分析,识别出开发过程中需要改进的地方,并向高层管理者推荐合适的改进方案。
缺陷纠正:每一个缺陷一旦被记录下来,都被标以"open"状态,指出其需要纠正。没有必要在软件发布前将每个发现的缺陷都纠正完,只有那些严重影响公司商业目标(包括质量目标)的缺陷才必须在软件发布前解决掉,其他缺陷可视具体情况在以后解决。
缺陷预测:开发组织常常进行源码分析,预测软件在进入测试阶段前还有多少缺陷。
六、静态测试
静态测试的最大特点,就是不需要执行被测软件就能完成。这是与动态测试相对而言,后者需要执行一次或多次被测软件。静态测试能够以相当低的代价发现软件当中的缺陷,包括需求文档以及其他与软件相关文档中的二义性和错误。静态测试和动态测试是互补的。
静态代码分析工具能够提供控制流和数据流信息,这些信息对审查小组理解代码以及发现可能的缺陷非常有用。目前,已存在一些商用和开源静态分析工具。IBM Rational的Purify以及Klockwork公司的Klockwork是两个针对C和Java程序的商用静态分析工具。LAPSE是针对Java程序的开源分析工具。
静态测试包括走查和审查。
走查是个非正式的过程,检查所有与源程序代码相关的文档。例如,需求文档是通过一个称作需求走查的过程来检查的;源程序代码是通过代码走查(也称同行代码评审)来检查的。走查要生成详细的报告,列出涉及被查文档的相关信息。
审查:相比走查,审查是个更加正规的过程。该术语常常与代码联系在一起。多家组织认为,正规的代码审查是一种以比采用动态测试更低成本提高代码质量的手段。已有多家组织声称,由于采用代码审查,极大地提高了生产率和软件质量。
代码审查通常由一个小组来完成,审查小组按照审查计划开展工作。审查计划包括以下要素:
(1)审查目的;
(2)被审查的工作产品,包括源程序代码以及需要审查的相关文档;
(3)审查小组组成、角色、职责;
(4)审查进度;
(5)数据采集表格,审查小组用来记录发现的缺陷、编码规则违背情况、各项审查工作所花时间等。
审查小组的成员分为协调人员、阅读人员、记录人员、编程人员等角色。协调人员负责整个审查工作并领导整个审查工作。由阅读人员来阅读源代码,可能要借助于代码浏览器以及大屏幕显示器,以便全组人员都能方便地看到代码。记录人员记录所有发现的错误以及讨论过的问题。编程人员是被审查代码的实际开发者,其在审查中的主要职责是帮助其他成员理解代码。审查过程必须是友好而非对立的。
七、测试类型(黑盒测试和白盒测试是两个最基本的测试技术。所有下面的C2-C4分类测试要么属于黑盒测试范畴,要么属于白盒测试范畴)
采用一个分类框架对大量测试技术进行分类。该框架包含5个分类因子,用于对属于动态测试范畴的测试技术进行分类。每个分类因子都是一个从特征集合到测试技术集合的映射。特征包括测试设计的依据、确定测试目标的问题、生命周期阶段或者软件制品。下面是5个分类因子。
C1.测试生成的依据
黑盒测试:
定义:在没有被测软件源代码的情况下,根据非形式化或形式化定义的需求文档设计测试,这种形式的测试一般被称作黑盒测试。如果需求文档是非形式化定义的,可以采用ad hoc技术或试探法,比如等价类划分和边界值分析
(非形式化)包括:ad hoc测试;边界值分析;类型划分;分类图;因果图;等价类划分;划分测试;判定测试;随机测试;语法测试等等。
基于模型或基于规范的测试:
定义:当需求被形式化定义后,可以应用基于模型或基于规范的测试,例如,通过采用一种或多种数学或图形记号,比如Z、状态图、事件顺序图,根据形式规范设计测试。这也是黑盒测试的一种形式。
(形式化)包括:状态图测试;FSM测试;结对测试;语法测试等等。
白盒测试:
定义:是指在测试活动中利用源代码进行测试用例的设计和评价。很少或几乎不可能孤立地采用白盒测试技术,因为一个测试用例包含测试输入和预期结果,测试人员必须利用需求文档来设计测试用例。在任何时候,只要有人声称他们采用的是白盒测试,就有充分的理由相信他们实际采用的是白盒与黑盒结合的某些测试技术。
包括:充分性评价;覆盖测试;数据流测试;域测试;变异测试;路径测试;结构测试;测试优化等等;
接口测试(属于黑盒测试):
定义:测试用例通常是采用组件的接口生成的。
包括:接口变异;结对测试等等。
C2.测试所在的软件生命周期阶段
单元测试(编码阶段):程序员在早期编码阶段编写代码,在与其他系统组件集成之前,他们需要测试自己的代码,这种类型的测试称为单元测试。在单元测试中,程序员关注的是开发的单元或小的组件,测试的目的是确保单元能够独立地正确工作。在单元测试期间设计的测试很可能不能用于集成和系统测试。
集成测试(集成阶段):当部分程序单元集成在一起,就形成一个大的组件或一个子系统,程序员需要对子系统进行集成测试。在集成测试阶段,测试的目的是确保一组组件能够如期望的那样工作,在此阶段,常常发现一些集成错误。集成测试阶段设计的测试也可能不能用于系统测试。
系统测试(系统集成阶段):当整个系统建成后,对它的测试称作系统测试。系统测试目的在于确保系统具备所有期望的功能,并且能够按照其需求规范要求的那样工作
回归测试(维护阶段):软件用户报告的错误,常常导致额外的测试和调试。由于相比整个软件而言,通常对软件所做的修改是非常小的,这样,就没有必要对整个系统进行测试。在这种情况下,通常进行回归测试。回归测试的目的在于确保修改后的系统能够按照其需求规范正确运行。当然,回归测试可以只执行整个系统测试用例集的一个子集。挑选的回归测试用例包括用于测试被修改代码的用例,以及测试其他可能受修改影响的代码的用例。
β测试(后续系统,预发布):通常,会在一个软件正式上市销售前,请一个仔细挑选过的用户群进行测试,这种形式的测试称为β测试。
验收测试:对于按合同交付的软件,在做出最终决定是否购买/部署该软件之前,签约客户会进行验收测试。
C3.具体测试活动的目标
功能测试:
安全保密性测试:
鲁棒性测试:是指测试一个软件针对未期望输入的健壮性。它不同于功能测试,因为鲁棒性测试用例是从有效(或期望)输入空间之外设计的,而在功能测试中,测试用例是从有效输入空间导出的。
举一个鲁棒性测试的例子——假设要求某个软件针对所有x>=0的值执行某项功能,然而并没有规定当x<0时软件应该怎么做。在这种情况下,鲁棒性测试应该要求针对x<0的情形对软件进行测试。由于需求并没有规定软件在有效输入空间外的行为,这里就需要对究竟是鲁棒性测试有一个清晰的理解。在有些软件中,鲁棒性可能只是意味着软件显示一个错误信息并退出,而在其他情况下,鲁棒性可能意味着要控制飞机实现安全着陆。
脆弱性测试:其目的在于检测软件是否存在漏洞,以防止未经授权的用户能够由此入侵到被测系统中来。如渗透测试。脆弱性测试就是安全保密性测试的一种形式
GUI测试:
操作测试:
可靠性测试:
入侵检测:
压力测试:在进行压力测试时,测试人员要检查软件在所施加压力下的行为。测试的目的在于发现被测软件在所给压力情况下能否继续运行正确。
性能测试:是指对软件按照预期的性能要求进行专门的测试。例如,可能会检查一个编译器是否满足规定的性能要求,比如每秒编译的代码行数。通常,性能要求都是针对特定硬件和软件配置而提出的。
负载测试:是指对软件加载一个或多个操作,以判断被测软件在不同的负载条件下能否按要求的那样继续运行。例如,可能会对一个数据库服务器加载来自大量模拟用户的请求。虽然服务器在只有一两个用户使用时工作正常,但当用户数量超过一定阈值时失效的方式却五花八门。
从某种意义上说,负载测试是另一种形式的压力测试。然而,负载测试可用来查明被测软件的性能及其行为的正确性。当测试目标是检查针对负载条件下的功能需求,被测软件是否运行正确时,负载测试就是某种形式的压力测试。当测试目标是评价在给定条件下软件执行某些操作的时间时,负载测试就是某种形式的性能测试。
负载测试也是某种形式的鲁棒性测试,主要测试未明确规定的需求。例如,可能没有准确地规定有关软件能够处理的最大用户数以及当用户数超过某个阈值时软件该做什么的需求,在这种情况下,负载测试允许测试人员来判断这个阈值,被测软件一旦超过这个阈值就陷入崩溃状态。
验收测试:
兼容性测试:
外设配置测试:
外国语言测试:
C4.被测软件制品的特点。
测试技术:被测软件制品的特征
组件测试:应用程序组件
等价类划分、基于有穷状态模型的测试以及本书中讨论的大多数其他测试生成技术:批处理
C/S测试:客户/服务器
编译器测试:编译器
设计测试:设计
编码测试:编码
事务流测试:数据库系统
OO测试:OO软件
OS测试:操作系统
实时测试:实时软件
需求测试:需求
Web服务测试:Web服务
C5.测试过程模型
瀑布测试模型:通常在临近开发过程结束时进行测试,静态测试和动态测试活动直到临近开发过程结束时才出现。
V测试模型:在开发过程的每一个阶段明确定义了测试活动,一旦得到需求,就可开展设计测试。
螺旋测试:应用于软件增量的测试,为演化软件开发而提出的。每一个软件增量都是一个软件原型,最后形成提交给用户的软件。它是一个测试策略,该策略可应用于任何增量式的软件开发过程,特别是从原型系统演化为最终应用系统的情况。在螺旋测试中,测试活动的复杂程度随着原型系统演化阶段的增加而增加。
敏捷测试:应用于敏捷软件开发方法学,如极限编程(XP)。敏捷测试推广下列思想。
(1)从需求分析阶段开始就在整个项目开发中包括与测试相关的活动;
(2)与客户密切合作,让他们以测试的方式定义需求;
(3)测试人员与开发人员相互协作,而不是对手;
(4)经常测试,小量测试。
测试驱动的开发:将需求定义为测试用例
八、软件测试的基础
测试生成、测试评价以及测试增强构成了软件测试的基础。