舰炮火控软件单元测试研究

2010-01-20 01:44曹晓勇王德伟
现代电子技术 2009年21期
关键词:单元测试

曹晓勇 王德伟 刘 希

摘 要:针对舰炮火控软件单元测试工作量大、效率低的问题及现状,基于软件单元测试的理论,分析研究了单元测试所关注的测试内容、测试方法、测试环境搭建以及测试用例设计等要点,同时结合某型号产品舰炮火控软件单元测试的实践,总结了舰炮火控软件单元测试的经验,并在此基础上提出了有效提高单元测试效率,从而提高舰炮火控软件质量的方法和途径。

关键词:舰炮火控软件;单元测试;静态分析;白盒测试;黑盒测试

中图分类号:TP311.5 文献标识码:A

文章编号:1004-373X(2009)21-013-03

Research on Unit Testing for the Software of Shipborne Gunnery Fire Control System

CAO Xiaoyong,WANG Dewei,LIU Xi

(Jiangsu Automation Research Institute,China Shipbuilding Industry Corporation,Lianyungang,222006,China)

Abstract:Aimed at the problem and actuality of mass workload and low efficiency in unit testing for the software of shipborne gunnery fire control system.Based on the fundamental theory of software testing,the essential points of unit testing,such as testing content,testing methods,testing environment building and testing cases designing are researched,the 〆xperience of unit testing for the software of shipborne gunnery fire control system is summarized.Some means and approaches to improve the efficiency of unit testing and the quality of software are proposed.

Keywords:shipborne gunnery fire control system Software;unit testing;static analysis;white box testing;black box testing

随着舰炮火控技术的不断发展,舰炮火控软件的精确度和复杂度越来越高,继而对火控软件的质量和可靠性要求也就相应提高。而软件测试不仅是保证软件可靠性的必要和有效手段,更是软件质量保证的关键步骤。从软件生命周期全过程来看,测试可分为单元测试、集成测试、确认测试、系统测试等阶段[1]。其中,单元测试是整个测试过程中最基础、最核心的一个环节,单元测试不仅要针对每一个模块进行,而且每个模块的每条语句至少要遍历一次,其工作量之大也是可想而知的[2]。那么,舰炮火控软件单元测试到底该如何进行,才能有效地提高测试效率,逐渐成为大家日益关注的问题。

1 单元测试概述

单元测试是针对软件设计的最小单位——模块进行的,其测试依据是软件的详细设计说明[3]。测试者根据详细设计说明和源程序,了解模块的输入、输出条件和逻辑结构,并通过测试来发现编码是否有误、程序逻辑结构是否合理、模块的功能实现是否正确、与详细设计文档要求是否一致等。单元测试主要包括功能测试和结构覆盖测试,针对有性能(运行时间或占用空间)要求的模块和单元,还有必要做性能测试。单元测试通常采用白盒测试为主,黑盒测试为辅的策略[4]。

2 单元测试关注要点

2.1 单元测试内容

在单元测试中,需要对以下五个方面的内容进行测试[5]:

(1) 模块接口测试。测试模块的数据流,主要指模块的形式参数与实际参数在个数、属性、顺序上是否匹配;全局变量的定义在各模块中是否一致等。

(2) 局部数据结构测试。模块的局部数据结构是常见的错误来源,这些错误主要体现在数据类型说明不正确或不一致;局部变量未初始化就被使用;初始值或默认值错误等。

(3) 路径测试。对执行路径和循环进行测试,通常采用白盒测试方法来设计测试用例,用以查找由于错误的计算、不正确的比较或不正常的控制流而导致的错误。

(4) 错误处理测试。对模块的容错能力进行测试,比较完善的设计要求模块能够预见出错的条件,并设置适当的出错处理对策,以便在程序出错时,能对出错程序进行安排,保证其逻辑上的正确性。

(5) 边界测试。重在检测以下问题:如在n次循环的第0次、1次、n次是否有错;运算或判断中取最大最小值时是否有错;数据流、控制流中刚好等于、大于、┬∮谌范ǖ谋冉现凳笔欠裼写淼取

2.2 单元测试的方法

单元测试的方法一般有三种:静态分析、黑盒测试、白盒测试。其中静态分析又称为静态测试,黑盒测试和白盒测试被称为动态测试

2.2.1 静态分析

静态分析是指不执行被测代码,人工或借助专用工具审查软件设计文档和程序源代码,对软件单元或模块的控制流、数据流、接口特性及表达式等进行分析,从而保证代码正确性、清晰性、规范性、一致性、算法高效性,并尽可能地发现程序中隐含的错误的过程[6]。通常,程序源代码的静态分析,包括从命名规则检查、寄存器使用、编码格式、出/入口连结、编程语言使用、存储器使用、测试和转移、可维护性、逻辑和程序多余物等十个方面对代码进行审查。按软件质量模型规定的相关度量指标对源代码的文本、注释、扇入/扇出数、圈复杂度等指标进行度量。

2.2.2 黑盒测试

黑盒测试也称功能测试或数据驱动测试。它是在已知软件单元所具有的功能的前提下,不考虑程序内部结构和内部特性,把程序看作一个不能打开的黑盒子,检查程序功能是否按照软件详细设计的规定正确实现、程序是否能正确地接收输入数据从而产生正确的输出信息,并且保持外部信息(如数据库或文件)的完整性[7]。

黑盒测试从原则上讲应是穷举输入测试,只有把所有可能的输入都作为测试情况使用,才能以这种方法查出程序中的所有错误。实际测试情况有无穷多个,而且测试人员不仅要测试所有合法的输入,还要对那些不合法但是可能的输入进行测试。显然,把输入数据的所有可能取值都进行测试,是不可能也是无意义的。设计黑盒测试的测试用例有很多种方法,例如等价类划分法、边界值分析法、错误推测法等。最常用的方法是等价类划分法。这种方法将测试空间的输入数据分为三类,即正常输入、边界输入和非法输入,每种输入还可进行更详细的划分,在设计测试用例时取每类的若干个数据作为输入数据,如果测试通过,可以肯定同类的其他输入也是可以通过的。这种方法不仅有助于提高测试用例的有效性,而且有助于提高黑盒测试的效率。

2.2.3 白盒测试

除黑盒测试以外,单元测试还需要从另一个角度即程序的逻辑结构来设计测试用例,并用逻辑覆盖率来衡量测试的完整性,即所谓的白盒测试[8]。对于白盒测试的逻辑覆盖率,一般有专门的覆盖率测试工具来完成。

白盒测试用例的设计方法是画出程序的逻辑结构图(如程序流程图或控制流图),并根据逻辑结构图设计测试用例。白盒测试的逻辑单位主要有语句、分支、条件、条件值、条件值组合、路径等。

一般来讲,与条件直接有关的错误主要是逻辑操作符错误,例如:将“||”写成“&&”,或在“!=”中漏了写“!”等,所以在具体的白盒测试中,只要采用分支覆盖与条件覆盖的组合,基本上可以发现这些错误,另一方面,要全部完成语句覆盖、条件覆盖、分支覆盖、路径覆盖的成本和代价是很高的,其工作量更是难以估计,仅条件值覆盖与条件值组合覆盖往往就需要设计和执行大量的测试用例。因此,从测试的投入和产出角度来说,进行白盒测试时,并不是覆盖的逻辑单位越多越好,不同关键等级的模块应采用不同的逻辑覆盖单位,这样才能最好地体现测试的有效性。

2.3 单元测试的环境搭建和用例设计

单元测试是针对程序最小单元的测试,单元本身通常不能单独运行,因此在单元测试时需要为被测单元设计桩模块和驱动模块。

(1) 驱动模块:相当于所测模块的主程序。它接收测试数据,将这些数据传送给被测模块,最后再输出实际测试结果。

(2) 桩模块:用于代替被测模块所调用的下层模块,其作用是返回被测模块所需要的数据和信息。

驱动模块、被测模块、桩模块三者共同构成了单元测试“测试环境”,如图1所示。

测试用例设计的目的是验证程序的功能、性能和结构,找出程序中隐含的错误和缺陷。测试用例设计的基本原则是[9]:

(1) 一个好的测试用例在于它能发现至今未能发现的错误或缺陷;

(2) 测试用例至少由测试输入和测试输出两部分组成;

(3) 设计测试用例时,应考虑到合理的和不合理的输入条件;

(4) 穷举测试是不可能的,但可以通过设计测试用例,覆盖所有的条件;

(5) 对发现错误和缺陷较多的程序段,应着重进行更深入的测试。

3 基于实践的测试经验和建议

舰炮火控软件是实时性要求较高的嵌入式软件,其软件与硬件具有极高的耦合度,在通用PC机平台上常常无法运行,需要特定的专用计算机硬件平台及专用外部设备。另外,虽然舰炮火控软件大多数采用的是结构化设计,但近年来随着舰炮火控软件技术的不断发展,面向对象的设计越来越多地被接纳和采用。

针对舰炮火控软件的这些特点,选择了LDRA公司的TestBed/Tbrun系列测试工具作为某型号软件产品单元测试的基本工具,并进行了静态分析、黑盒测试和白盒测试。

根据要完成的测试任务,采用了如图2所示的基于目标机的交叉测试环境。宿主机是通用Windows平台,安装Tornado 2.0开发环境以及测试工具LDRA Testbed,完成被测模块的插装及编译链接,产生可执行的目标代码。宿主机与目标机之间通过网络完成代码下载、测试数据获取以及覆盖率分析。

通过本次测试实践,获得如下经验和建议:

(1) 在结构化程序中,所谓的单元是指函数,而在面向对象的程序中,单元的概念发生了变化,而是指类。从对某型号软件产品单元测试的实践来看,以类作为测试单位,复杂度高,可操作性较差,因此仍然主张以函数作为单元测试的基本单位,但可以用一个测试类来组织某个类的所有测试函数。需要说明的是,单元测试不应过分强调面向对象,因为局部代码依然是结构化的。单元测试的工作量较大,简单实用高效才是硬道理。

(2) 静态分析能够有效地发现30%~70%的语法错误和编码错误,但很难挖掘出程序代码中的隐性错误和缺陷,尤其是需要软件动态运行才能暴露出来的错误。黑盒测试能够动态检查并较好地发现软件单元的功能性错误,但其测试的完整性却难于测量。而白盒测试不仅能够动态运行检查软件单元的逻辑错误,而且其

覆盖率测试恰恰具有易于衡量测试完整性的优点。所以对于单元测试来讲,三者之间具有极好的互补性,通常推荐的单元测试步骤和过程是,先进行静态分析,然后进行黑盒的功能测试,黑盒测试后统计覆盖率,如果覆盖未达到测试计划中所规定的标准,那么针对未被覆盖的语句部分代码进行逻辑分析,并结合白盒测试的测试用例再次对软件单元进行测试,直到满足覆盖要求。同时,对无法覆盖的语句或分支也要给出说明和理由。

(3) 对于白盒测试的几种逻辑单位的测试,通常推荐的步骤和方法是“先简单后复杂”。例如,进行黑盒测试后统计覆盖率,先检查是否有语句未覆盖,若有则设计测试用例覆盖它,然后用同样方法完成条件覆盖、分支覆盖和路径覆盖,这样既检验了黑盒测试的完整性,又避免了重复的工作,用较少的时间成本获得了较高的测试效率。

4 结 语

随着火控技术不断发展,舰炮火控软件的工程化水平也在不断改进,对软件测试的要求也在进一步提高,在这种情况下如何更好地开展软件测试工作,如何将软件测试的理论和方法更好地运用到软件产品的测试实践中去,是很有意义和价值的问题。本文论述了软件单元测试的理论和方法,介绍了单元测试在实际工作中的实践和经验,希望对舰炮火控软件的测试工作能够有进一步的推动和提高。

参考文献

[1] 朱少民.软件测试方法和技术[M].北京:清华大学出版社,2005.

[2]John D Musa.软件可靠性工程[M].北京:机械工业出版社,2003.

[3]何永军.声纳嵌入式软件的单元测试及结构覆盖率测试方法[J].声学与电子工程,2004(4):45-47.

[4]Roger S Pressman.软件工程——实践者的研究方法[M].梅宏,译.北京:机械工业出版社,2004.

[5]张猛,毛亮.航天嵌入式软件的单元测试方法探讨[J].航天器工程,2006,15(2):32-35.

[6]Dirk Huberty.软件质量与软件测试[M].马博,赵云龙,译.北京:清华大学出版社,2003.

[7]Shari Lawrence Pfleeger.软件工程——理论与实践[M].北京:高等教育出版社,2001.

[8]宫云战.软件测试[M].北京:国防工业出版社,2006.

[9]Ron Patton.软件测试[M].北京:机械工业出版社,2000.

作者简介 曹晓勇 女,1978年出生,河南漯河人,工程师,学士。研究方向为火控模型与软件,嵌入式软件测试。

王德伟 男,1982年出生,山西原平人,助理工程师,学士。研究方向为火控模型与软件。

刘 希 男,1986年出生,湖北襄樊人,助理工程师,学士。研究方向为嵌入式软件测试。

猜你喜欢
单元测试
“三角形”单元测试卷
“整式的乘法与因式分解”单元测试题
“勾股定理”单元测试题
“整式的乘法与因式分解”单元测试卷(提高卷)
《一次函数》单元测试题
《一次函数》单元测试题
一年级上册第五单元测试
一年级上册一、二单元测试
第五单元测试卷
第六单元测试卷