软件工程之软件测试

软件测试

软件测试的过程

软件工程之软件测试

测试过程需要三类输入:

(1)软件配置。包括软件需求规格说明、软件设计规格说明、源程序代码等;

(2)测试配置。包括测试计划、测试用例等。

(3)测试工具。为了提高软件测试效率,减少测试过程中的手工劳动,可使用一些专门的测试工具,如测试数据自动生成
测试结果分析程序、驱动测试的测试数据库等。 

软件测试的目的

1.测试是程序的执行过程,目的在于发现错误

2.一个好的测试用例在于能发现至今为发现的错误

3.一个成功的测试是发现了至今未发现的错误的测试

 

软件测试的原则

1.应当把尽早地和不断地进行软件测试作为软件开发者的座右铭。

2.测试用例应由测试输入数据和对应的预期输出结果这两部分组成。

3.程序员应避免检查自己的程序。

4.在设计测试用例时,应当包括合理的输入条件和不合理的输入条件。

软件工程之软件测试

软件测试的方法

软件测试的种类大致可以分为人工测试和基于计算机的测试。基于计算机的测试有两种方法。
 

1.黑盒测试

(1)、黑盒测试方法是把程序看成一个黑盒子,完全不考虑其内部结构和处理过程,只检查程序的功能是否符合它的需求规格说明。可见,黑盒测试是在软件的接口处进行的,一方面看其是否能对合法的数据得出正确的结果,另一方面看它是否能对非法的数据进行正确的处理。

(2)、黑盒测试是一种宏观功能上的测试,该方法适合测试部门的测试人员或用户。

2.白盒测试

(1)、白盒测试方法是把程序看成一个打开的盒子,测试人员对程序所有逻辑路径进行测试,在不同检查点输出结果,与预期的结果比较,确定程序是否有错。使用白盒测试法时,为了做到穷尽测试,程序中每条可能的通路至少都应该执行一次。

(2)、白盒测试是一种程序级的微观上的测试,不适合于大单元、大系统的测试,只适合于
很小单元的测试,以及从事软件底层工作、生产构件的测试人员进行的测试。

测试与软件开发各阶段的关系

软件开发过程是一个自顶向下,逐步细化的过程。

测试过程是依相反顺序安排的自顶向上,逐步集成的过程。

软件工程之软件测试

 

软件测试步骤

与开发过程类似,测试过程也必须分步骤进行,后一个步骤在逻辑上是前一个步骤的继续。软件从编码结束到交付用户使用,需要经过单元测试、组装测试、验收测试和系统测试 4 个步骤。

软件工程之软件测试

 

单元测试

单元测试是软件测试的第一步,是针对软件设计的最小单位——程序模块,进行正确性检验的测试工作 
 

一、单元测试的内容;

   1、模块接口测试;
 

        单元测试首先对通过模块接口的数据流进行测试。如果发现数据不能按预定要求进出模块,所有其他测试都是不切实际的。接口测试主要从如下几个方面考虑:
        (1) 模块的形参和其驱动模块送来的参数的个数、类型、次序是否一致;
        (2) 模块传送给被调用模块的参数与其桩模块的参数的个数、类型和次序是否一致;
        (3) 模块传送给库函数的变量个数、类型次序是否正确;
        (4) 全局变量的定义和用法在各个模块中是否一致;
        (5) 所使用的外部文件的属性是否正确,打开文件的语句是否正确,缓冲区大小是否与记录长度相匹配,文件结束判断处理是否一致。 

   2、局部数据结构测试
 

        模块内部数据是否完整,内容、形式、相互关系是否有错常常是软件错误的主要来源。
对局部数据结构的测试时应做如下考虑:
        (1) 错误或不相容的数据说明或使用了尚未初始化的变量;
        (2) 错误的初始值或不正确的缺省值;
        (3) 错误的变量名或数据类型不相容;
        (4) 溢出(上溢或下溢)或地址异常;
        (5) 全局数据对模块的影响。 

   3、重要路径测试
 

        由于通常不能进行穷尽测试,因此,在单元测试期间应选择最有代表性、最可能发现
错误的执行路径进行测试。重要路径测试方案应重点测试由于错误计算、不正确的比较或
不适当的控制流而造成的错误。常见错误如下:

        (1) 运算的次序错误(误用了运算符的优先级);
        (2) 混合运算对象的类型彼此不相容;
        (3) 变量初始值不正确;
        (4) 精度不够,或由于精度问题两个量不可能相等时,程序中却期待着相等条件的出现;
        (5) 错误地修改循环变量,错误的或不可能达到的循环终止条件;
        (6) “差 1”错(多循环 1 次或少循环 1 次);
        (7) 当遇到发散的循环迭代时循环不能终止。
 
 

   4、错误处理测试

        好的模块设计应能预见出错的条件,并设置相应的出错处理。这样,程序一旦发生错误就会按照预定的方法进行处理,保证逻辑上的正确性。这种错误处理应当是模块功能的一部分,也应是测试的内容之一。对错误处理进行测试时应重点考虑下列问题:
        (1) 对可能出现错误的描述是否难以理解;
        (2) 出错的描述不足以对错误定位,或足以确定出错的原因;
        (3) 显示的错误与实际的错误不符;
        (4) 对错误的条件处理不正确;
        (5) 在对错误进行处理之前,错误条件已经引起系统的干预。 

   5、边界测试
 

        边界测试是单元测试中最后的、也可能是最重要的工作。程序常常在边界上出现错误。
例如,在一段程序内有一个 n 次循环,当到达第 n 次循环时就有可能出错。因此,要特别
注意数据流、控制流中恰好等于、大于或小于确定的比较值时出错的可能性。要精心设计
测试用例对这些地方进行测试。 

 

二、单元测试的步骤;

       当每个模块的代码编制完成,并经过评审和验证确认没有语法错误后,就可以进行单元测试。单元测试可分为以下 3 个步骤进行。 

1、配置测试环境

     模块是软件中一个单独的编译单位,而不是一个单独的执行单位。所以在测试时要为模块设计两类附加模块,模拟模块的实际运行环境。 
 

(1)驱动模块:驱动模块是用来调用被测模块的模拟模块。通常驱动模块就是一个“主程序”,主要用来接收测试数据,把这些数据传送给被测试的模块,并且打印出有关结果。 

(2)桩模块:桩模块是用来代替被测试的模块所调用的模块,又称存根模块或支撑模块。它接收被测试模块的调用,可以做最少量的数据操作,打印出对入口检验或操作的结果,并且把控制归还给调用它的模块。 

2、编写测试数据

软件工程之软件测试

 

3、进行多个模块的并行测试

     这三个测试步骤都是基于计算机的单元测试。为了提高测试效率,在进行计算机测试之前,常常首先对源程序代码进行人工的静态测试。 
 


 

集成测试

       经过单元测试之后,需要将所有模块按照设计要求组装成为系统,在组装的过程中可以同时进行测试,也就是集成测试。集成测试的主要目标是发现与接口有关的问题。

      集成测试根据模块的组装方式体现出两种测试方式:非渐增式测试和渐增式测试。

一、非渐增式测试

     非渐增式测试是把已经过测试的所有模块一次性组装在一起,然后进行整体测试。由于程序中不可避免地存在涉及模块间接口、全局数据等方面的问题,测试中会遇到许多错误。而在一个庞大的程序中诊断定位一个错误是非常困难的,并且一旦改正一个错误后,往往会出现新的错误。因此,这种测试往往不可能一次成功,查错和改错都很困难。在集成测试时普遍使用渐增式测试方法。 
 

二、渐增式测试

     渐增式测试是把已经过测试的模块逐个进行组装,在组装的过程中进行测试,最后得到完整的系统。这种测试方式也可在各模块没有进行测试的前提下进行。 

1、自顶向下集成:这种集成方式是从主控模块开始,沿着控制层次自顶向下进行组装。 组装过程中添加
模块时可采用深度优先策略或广度优先策 

2、自底向上集成:这种集成方式是从软件结构的最底层的模块开始,自底向上组装和测试。对于一个给
定层次的模块,它的各级子模块已经组装并通过测试,所以不再需要桩模块。 

3、混合的集成测试:常用混合方式有如下 3 种 
 

(1) 衍变的自顶向下的集成测试:强化对输入/输出模块和引入新算法模块的测试,并自底向上组装成为功能相当完整且相对独立的子系统,然后由主模块开始自顶向下集成测试。
(2) 自底向上-自顶向下的集成测试:首先对含读操作的子系统自底向上直至根结点模块进行组装和测试,然后对含写操作的子系统自顶向下进行组装和测试。
(3) 回归测试:采用自顶向下的方式测试所修改的模块及其子模块,然后将这一部分视为子系统,再自下向上测试,以检查该子系统与其上级模块的接口是否适配。 

 


 

验收测试

       验收测试又称为确认测试。集成测试消除了软件接口的错误,系统已成为完整的软件包。验收测试主要由用户参加测试,检验软件规格说明的技术标准的符合程度,是保证软件质量的最后关键环节。  
 

一、有效性测试

      有效性测试是在模拟的环境(也许就是开发环境)运用黑盒测试的方法,验证软件是否满足需求规格说明书列出的需求。通过实施预定的测试计划和测试步骤,确定软件的特性是否与需求相符,确保所有的软件功能需求都能得到满足,所有的软件性能需求都能达到,所有的文档都是正确且便于使用。同时,对其他软件需求,如可移植性、兼容性、出错自动恢复、可维护性等进行测试,确认是否满足。

      有效性测试有两种结果:一是功能和性能与用户要求一致,软件是可以接受的。二是功能或性能与用户的要求有差距,这时就提交一份问题报告。 

二、软件配置复查

       软件配置复查是验收测试的一项重要任务。其目的是保证软件配置的所有成分都齐全,
各方面的质量都符合要求,文档内容与程序完全一致,具有软件维护阶段所必需的细节,
而且全部文档都已经编好目录。
 
 


 

系统测试

       系统测试是将通过验收测试的软件,作为基于计算机系统的一个元素,与计算机硬件、外设、某些支持软件、数据和人员等其他系统元素结合在一起进行的综合测试。一般包括以下几个方面。
       (1) 恢复测试:通过系统的修复能力,检测重新初始化、数据恢复、重新启动、检验点设置是否正确,以及人工干预的平均恢复时间是否在允许范围内。
       (2) 安全测试:设计测试用例,安全保密措施,检验系统是否有安全保密的漏洞。
       (3) 强度测试:设计测试用例,检验系统的能力最高能达到什么实际限度,让系统处于资源的异常数量、异常频率、异常批量的条件下运行测试系统的承受能力。一般取比平常限度高 5~10 倍的限度做测试用例。 

 

       (4) 性能测试:设计测试用例测试并记录软件运行性能,与性能要求相比较,检查是否达到性能要求规格。这项测试常常与强度测试相结合进行。 
 

 

调试技术

        软件调试是在测试发现错误之后诊断并排除错误的过程。测试是为了尽可能地发现错误,但这并不是最终目

的,软件工程的根本目标是开发出高质量的完全符合用户需要的软件产品。因此,在进行成功的测试后必须进行软件调试。
 

       调试的主要任务有两项:一是确定程序中错误的确切性质和位置,二是对程序进行修改、排除错误。 

 

调试技术

调试的目标在于找到软件错误的原因并加以改正。 
 

1.强行排错

       这是一种最常用的、效率较低的调试技术。它不需要过多的思考,直接打印出内存中的内容,希望从中找出错误原因所在。可以在程序的特定部位设置打印语句,跟踪程序的 执行,监视重要变量的变化;也可以利用某些程序语言的调试功能或专门的交互式调试工具,通过设置断点等方法分析程序的动态过程。在采用这一技术时,必须有明确的目的,尽量减少无关信息的输出,以提高设计效率。 
 

2.回溯法

回溯是在小程序中常用的一种有效的调试技术。具体做法是,分析错误表象,确定症状位置,人工沿程序的控制流往回追踪源程序代码,直到找到错误原因为止。对于小程序,回溯法可能把错误范围缩小到程序中的一小段码,仔细分析这段代码不难确定出错的位置。但是,随着程序规模的扩大,应该回溯的路径数目也越来越大,以至于彻底回溯变成完全不可能。 

3.归纳法

   归纳法是从个别现象推断出一般性结论的思维方法。采用归纳法调试程序的过程为:首先把和错误有关的数据组织起来进行分析,以便发现可能的错误原因。然后导出对错误原因的一个或多个假设,并利用已有的数据来证明或排除这些假设。如果已有的数据尚不足以证明或排除这些假设,则需设计并执行一些新的测试用例,以获得更多数据。
 

软件工程之软件测试

 

4.演绎法

       演绎法是从一般原理或前提出发,经过排除和细化的过程推导出结论。采用这种方法调试程序时,首先设想出所有可能的出错原因,然后试图用测试来排除每一个假设的原因,如果测试表明某个假设的原因可能是真的原因,则对数据进行细化以精确定位错误。

软件工程之软件测试

 

 
 

调试原则
 

1.查错的原则

(1)、注重头脑的分析思考,不要过分依赖计算机

最有效的调试方法是用头脑分析与错误征兆有关的信息。一个能干的程序调试员能做到不使用计算机就能够确定大部分错误的性质和位置。
(2)、把调试工具仅当作辅助手段
调试工具只能提供一些辅助调试的信息,这些信息可能帮助调试人员分析思考,但决不能代替思考。在调试过程中主要应用的仍然是调试员的逻辑思考。
(3)、 避免试探法,至多把它当作最后手段
试探法是一种碰运气的盲目行为,它的成功机会很小,而且还常把新的错误带到问题中来。这是初学调试的人常犯的一个错误(总试图修改程序来解决问题)。
(4)、 避开死胡同
这是我们干任何事都应遵循的原则。当调试工作进入死胡同,找不到任何解决问题的方法时,最好暂时把问题抛开,清醒一下头脑。可以向其他人讲解这个问题,用语言把逻 

2.排错的原则

(1)、注意错误的群集现象
当在某一程序段发现有错误时,在该程序段中还存在别的错误的概率也较高。因此,在修改一个错误时,还要查其近邻,看是否还有别的错误。
(2)、提出的修改应能解释与这个错误有关的全部线索修改错误的一个常见失误是只修改了错误的征兆,而没有修改错误的本质。如果提出的修改不能解释与这个错误有关的全部线索,就表明只修改了错误的一部分。
(3)、慎重对待每一个错误的修改
对程序的任何修改都可能会带来副作用,即引进新的错误。为了不至于改正了一个错误而引入更多的其他错误而“得不偿失”,因此,调试员应慎重对待第一个错误的修改。在修改软件错误之前,应仔细考虑这些问题:是否同样的错误也存在于程序的其他地方;将要进行的修改可能会引入的“下一个错误”是什么;为防止今后出现类似的错误应该做什么。另外,修改了一个错误之后,必须进行回归测试,以确认是否引进了新的错误。