软件工程概论(八)测试程序

I. Software faults and failures

故障识别(fault identification)是确定由哪一个故障或哪些故障引起失效的过程
故障去除(fault removal)/故障改正(fault correction)则是修改系统使得故障得以去除的过程

Types of faults

1、算法故障

对于给定的输入,产生不合适的输出。这些故障有时仅通过读程序(称为桌上检查desk checking)或者通过提交输入就能找出来。
典型的算法故障包括,分支太早,分支太迟,对错误的条件进行了测试,忘记了初始化变量或忘记设计循环不变量,忘记对特定的条件进行测试(除0),对不合适的数据类型进行比较。

2、语法故障

比如缺少逗号

3、计算故障和精度故障

一个公式的实现是错误的或计算结果没有达到要求的精度

4、文档故障

文档与程序实际做的事不一样

5、压力故障或过载故障

超过需求描述中的最大负载时发生的故障,这些特性在程序设计中表现为队列的长度、缓冲区大小、表的维度等的限制。

6、能力故障或边界故障

系统的活动达到指定的极限时,系统性能会变得不可接受。测试小组可以帮助维护小组理解将来提高系统能力的可能性。能力条件还应该用相关的磁盘访问数、中断数、并发运行的任务数以及类似的与系统相关的测量来检查。

7、计时故障或协调故障

在开发实时系统时,一个关键的考虑因素是几个同时执行的或按仔细定义的顺序执行的进程之间的协调问题。当协调这些事件的代码不适当时,会出现计时故障或协调故障。

8、吞吐量故障或性能故障

系统不能以需求规定的速度执行。这些是不同类型的计时问题:时间约束是根据客户需求写入系统性能中,而不是根据协调的需要。

9、恢复故障

当系统遇到失败时,不能表现的向设计人员希望的或客户要求的那样。

10、硬件和系统软件故障

当提供的硬件和系统软件实际上并没有按照文档中的操作条件和步骤运作时发生的故障。

II. Testing issue

Test options

在交付系统之前,要完成多种测试。有些测试依赖于正在测试的对象,构件、一组构件、子系统或整个系统,其它的测试依赖于我们想要了解的事情,系统能否按照设计、需求、客户的期望进行工作。

Test organization - testing steps!

在开发一个大型系统的时候,测试通常分为若干阶段 Module testing, component testing, or unit testing

首先,将每个程序构件与系统中的其它构件隔离,对其本身进行测试,这样的测试称为模块测试、构件测试或单元测试。它们验证,针对设计预期的输入类型,构件能否适当地运行。应当在受控的环境下进行,针对输入和输出检查内部数据结构、逻辑和边界条件。

Integration testing

当对这些构件已经完成了单元测试之后,下一步就是确保构件之间的接口正确定义和处理。集成测试是验证系统构件能否按照系统和程序设计规格说明中描述的那样共同工作的过程。

System testing - function test, performance test, acceptance test, and installation test

一旦我们能够确保构件之间的信息传递是与设计相符的,就要对系统进行测试以确保它具有期望的功能。

功能测试
功能测试是对系统进行评估,以确定集成的系统是否确定执行了需求规格说明中描述的功能。其结果是一个可运转的系统。

性能测试
功能测试将正在构建的系统与开发人员的需求规格说明进行比较。而性能测试将系统与这些软件和硬件需求的剩余部分相比较(除了功能的),在客户实际工作环境中成功执行时,时确认的系统(validated system)

验收测试
与客户一起执行验收测试,根据客户的需求描述对系统进行检查。
在完成验收测试后,验收的系统安装在将要使用的环境中。

安装测试
最后的安装测试是确保系统将按照它应该的方式来运行。

Testing techniques!

对于测试对象(构件、一组构件、子系统、系统)的视图会影响测试的方式。
在黑盒和白盒之间找到平衡。通常,测试方法的选择依赖于诸多因素,包括,可能的逻辑路径数目,输入数据的性质,涉及的计算量,算法的复杂性。

Black box

如果从外部观察测试对象,将其看作是一个不了解其内容的闭盒或黑盒,那么,我们的测试就是向黑盒提供输入数据,并记录产生的输出。在这种情况下,测试的目的是确保每一种输入都被提交,并观察到输出与预期输出的匹配情况

优点在于免受强加给测试对象内部结构和逻辑的约束
缺点在于无法进行完备的测试

White box

将测试对象看成是一个开盒,根据测试对象的结构用不同的方式来进行测试,但覆盖所有路径也是不可能的。

III. Unit testing//单元测试

Examining the code

Code walkthroughs代码走查!

在走查的过程中,程序员向评审小组提交代码及相关文档,然后评审小组评论它们的正确性。程序员领导并且掌控讨论,讨论的气氛是非正式的,注意力是集中在代码上而不是集中在编码者身上。虽然项目管理人员也可能在场,但走查对程序员的业绩评价并没有影响,它是与测试的总目标相一致的:发现故障,但是不必修改它们。

Code inspections代码审查

在审查中,评审小组按照一个事先准备好的关注问题清单来检查代码和文档。
审查代码通常包括若干个步骤。首先召开小组会议,讨论代码概述和小组审查目标的描述。然后,小组成员单独准备第二次小组会议。每名审查人员研究代码及其相关文档,记录发现的故障。最后,在小组会议上,小组成员报告他们发现的故障,记录在讨论个人发现的过程中发现的额外错误。有时,个人发现的故障被认为是假阳性的:似乎是故障,但实际上审查小组认为并不是真正的问题。
审查小组成员的选择是根据审查目标进行的,有时,一个小组成员将扮演不止一个角色。如同走查一样,审查评价的是代码而不是编码者,并且其结果并不反映在业绩评价中。

Success of the code reviews

代码评审取得的成就
评审在检测故障方面显得格外成功,并且通常是组织机构中的一个强制措施或最好实践。

Test thoroughness!!(写测试路径)

要完全的测试代码,可以基于代码操纵的数据,至少使用下面几种方法中的一种来选取测试用例

语句测试:在某个测试中,构件中的每条语句至少执行一次 分支测试:对代码中的每个判定点,每个分支在某个测试中至少选择一次。
路径测试:通过代码的每条不同的路径在某个测试中至少执行一次。
定义使用的路径测试:从每个变量的定义到该定义的使用的每一条路径,都在某个测试中得到执行。
所有使用的测试:测试集至少包含从每一个变量的定义到通过其定义可到达的每一个使用的一条路径。
所有谓词使用/部分计算使用的测试:对于每一个变量以及该变量的每一个定义,测试至少包含从变量定义到其每一个谓词使用一条路径。如果还有此描述没有覆盖的定义,那么加入计算使用,使得每一个定义都被覆盖。
所有计算使用/部分谓词使用的测试:对于每一个变量以及该变量的每一个定义,测试至少包含从变量定义到其每一个计算使用的一条路径。如果还要此描述没有覆盖的定义,那么加入谓词使用,使得每一个定义都被覆盖。

IV. Integration testing//集成测试

1、Bottom-up integration

通过合并构件来测试较大型系统的方法称为自底向上测试。当使用这种方法的时候,每一个处于系统层次中最低层的构件首先被单独测试。接着要测试的是那些调用了前面已测试构件的构件。反复的采用此方法,直到所有的构件都被测试完毕。
当很多底层构件是常被其它构件调用的通用实用例程的时候,当设计是面向对象的时候,或者当系统集成大量独立的复用构件时候自底向上的方法是很有用的。

优点: 对面向对象程序来讲,自底向上测试通常是最为明智的选择。

缺点:
顶层构件通常是最重要的,但却是最后测试的构件。顶层指导主要的系统活动,而底层通常执行更为普通的任务。底层更概括,而较低层次更为具体。
有时顶层故障反映的是设计中的故障,这些问题应该在开发中尽快改正,而不是等到后期。
顶层构件通常控制或影响计时。当系统大部分处理依赖于计时的时候,就很难自底向上的测试系统

2、Top-down integration

自顶向下方法在很多方面都是自底向上方法的逆过程。顶层构件通常是一个控制构件,是独立进行测试的。然后,将被测构件调用的所有构件组合起来,作为一个更大的单元进行测试。重复执行这种方法,直到所有构件都被测试。
自顶向下测试并不需要驱动程序。另一方面,编写桩有可能比较困难,因为他们必须允许测试所有的可能情况。桩是测试的一个重要部分,并且它的正确性可能会影响测试的有效性。

优点:
可以根据被检查的功能来定义测试用例
任何关于功能可行性的设计故障或主要问题都可以在测试的早期进行处理,而不是等到测试的后期

缺点:
测试中可能需要大量的桩。避免该问题的一个方法是在进行合并之前对每一层的构件进行单独的测试,而不是一次性的包含完整的一层。
对每一层中的构件进行单独的测试会引入另一个难题:对每一个构件,既需要桩,又需要驱动程序,从而导致更多的编码和潜在的问题。

3、Big-bang integration

当所有构件都分别经过测试,再将他们合在一起作为最终系统进行测试,看看这个系统是否能一次运行成功,该方式称为一次性测试。
实际上,由于一次性集成测试存在着若干缺点,因此,在任何系统中都不推荐使用它。首先,它同时需要桩和驱动程序来测试独立的构件。其次,因为所有的构件是一次性地进行合并,很难发现引起失效的原因。最后,很难将接口故障与其它类型的故障区分开来。

4、Sandwich integration

将自顶向下策略与自底向上策略结合起来,形成了三明治测试方法。这种方法将系统看成三层,就像一个三明治。目标层处于中间,目标上面有一层,目标下面有一层。在顶层使用自顶向下方法,而在较低层使用自底向上方法。测试集中于目标层,目标层是根据系统特性和构件层次结构来选择的。
三明治测试允许在测试的早期进行集成测试。通过在最开始就对控制和实用程序进行测试,它还将自顶向下测试和自底向上测试的优点结合起来。但是在集成之前,它没有单独的、完全的测试构件。经过修改的三明治方法的一个变种,允许在将较上层的构件和其它构件合并之前,线对这些较上层的构件进行测试

5、Comparison of the strategies

集成策略的选择不仅依赖于系统特性,而且依赖于客户期望。

集成策略的比较

无论选择什么样的策略,测试的每个构件都只合并一次。而且,绝不要为了简化测试而修改构件。桩和驱动程序是单独的、新的程序,而不是现有程序的临时修改。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值