计算机软件测试技术概述

2023-01-07

1975年, Good enough等首次提出了软件测试理论, 同年Hua ng全面讨论了测试过程和测试准则。1 9 8 2年在美国北卡莱纳大学召开了第一次软件测试技术会议, 这次会议成为软件测试发展史上的一个重要里程碑。随后, 各国学者在测试理论与测试方法上百花齐放, 使得软件测试理论和方法逐步应用到软件开发过程中来。但从实际应用效果看来, 无论是测试技术还是测试方法都远远不能满足现在软件测试的需求。

软件测试的定义是在1983年由IEEE在软件工程标准术语中给出的:使用人工或自动手段来运行或评价某个系统或系统部件的过程, 其目的在于检验它是否满足规定的需求;或是弄清预期结果和实际结果之间的差别。该定义非常明确地指出了软件测试是以检验是否满足需求为目标。G..J.Myers认为软件测试是为了找出错误和缺陷而进行的, 而不是为了证明软件的正确性。

1 软件质量保证与软件测试

随着对计算机需求与依赖的与日俱增, 计算机软件数量激剧膨胀, 软件系统的规模也更加庞大, 如地震预测、天气预报、太空飞行等都是极其复杂的软件系统, 代码规模均在百万行以上, 如Windows NT操作系统的代码就大约有3 2 0 0万行。软件质量保证的技术发展水平对世界经济有重大的影响。1996年Ariane5运载火箭的发射失败等都是由软件故障引起的。2 0 0 2年美国国家标准与技术局研究发现, 全美每年软件测试的花费估计在2 2 2~5 9 5亿美元, 大约占美国国内总产值0.6%。这个数字还不包括由关键任务软件的灾难性故障所造成的损失。

随着软件在各行各业的广泛应用, 软件质量已经越来越受到社会的普遍关注。随着软件规模的不断扩大, 复杂程度也不断提高, 特别是随着软件开发技术迅猛发展, 面向对象软件开发等方法的出现和软件开发工具的使用, 使得软件质量更加难以度量。

软件质量保障涉及到软件开发生命周期的各个阶段, 从需求获取开始延续到软件维护。软件测试是保证软件质量, 提高软件可靠性的关键。G..J.Myers在软件测试经典著作《The Art of Software Testing》中给出了软件测试的定义:软件测试是指通过执行程序去找出软件错误的过程。Bill Hetzel在1983年也给出测试定义:测试是指为评价一个程序或系统展开的各种活动, 测试是度量软件质量的一个过程。虽然他们的定义目前看来具有一定的局限性, 但仍然具有指导意义。

软件测试是一项费时费力的过程, G..J.M y e r s指出软件测试所花费的代价大约占软件开发总代价的5 0%以上, 随着人们对软件测试重要性的认识越来越深刻, 软件测试阶段在整个软件开发周期中所占的比重日益增大。现在有些软件开发机构将研制力量的4 0%以上投入到软件测试之中;对于某些性命攸关的软件, 其测试费用甚至高达所有其他软件工程阶段费用总和的3到5倍。尽管人们在软件开发过程中也采用形式化方法描述和证明软件规约, 并采用程序正确性证明、模型检验等方法保证软件质量, 但是这些方法都存在一定的局限性, 尚未达到广泛实用阶段。因此, 程序代码最终体现了软件的质量, 无论是从软件开发方法学还是软件测试自身的效益看, 软件测试在今后较长时间内仍将是保证软件质量的重要手段。

2 基于结构的测试用例生成技术

结构化的测试属于白盒测试范畴, 测试用例是根据程的内部结构来设计, 如程序的语句、路径、分支、条件或其他特定容易导致程序出错的节点。结构测试有三种测试用例生成方法:随机测试用例生成方法、面向目标的测试用例生成方法和面向路径的测试用例生成方法。对于给定的程序结构 (如分支、路径等) , 随机测试的数据生成方法是在输入域内随机选取测试用例, 使得给定语句或分支被执行。

面向路径的测试用例生成分为基于符号执行和基于实际程序执行的测试用例生成两类。符号执行允许程序输入常量、符号值、符号表达式等, 以符号计算代替实际执行的数值计算, 产生一个符号输入值的代数表达式-路径约束, 它是选定路径的谓词系统。实际上是对输入数据的限制要求, 由多个不等式 (等式) 组成。通过求解不等式, 求取满足路径上各限制谓词的测试数据。若不等式无解, 则相应的路径为不可行路径。D e M i l l o等提出一种基于故障的测试产生方法, 用代数约束来描述检测特定类型故障的测试数据。

符号执行能够判定路径的可行性, 一次符号测试的结果代表了一类普通测试的运行结果。但在遇到循环、过程调用、动态数据结构、数组和指针处理时, 符号执行实现困难。基于程序实际执行的测试数据生成方法中, Korel提出对于选定路径上不满足要求的分支, 利用分支函数极小化, 确定新的输入值, 直至找到输入数据, 使程序执行沿选定路径进行。K o r e l提出的程序执行和分支函数极小化方法解决了符号执行中对数组和指针难于处理的缺陷, 但由于每次测试都只考虑一个谓词和一个输入变量, 因此即便路径中的分支条件是输入的线性函数时, 也需要进行大量的叠代才能自动生成一个满足条件的新输入。

G u p t a等利用迭代逼近法, 求取满足选定路径上所有谓词的输入值。每次迭代中, 执行与选定路径谓词有关的语句, 得到一个线性约束集, 用高斯消去法求解线性约束集, 获得一个输入增量, 进而得到下次迭代的输入值, 最终产生选定路径的测试数据。Gupta提出的算法同时考虑多个谓词和多个输入变量, 利用随机选择的一组初始输入通过叠代自动生成一组满足该给定路径的新输入, 该算法由于只采用线性函数来进行叠代, 因此只对线性函数有效, 而对于非线性函数则效果较差。Gotlieb等提出用约束求解的方法生成测试数据, 利用“静态单一指派” (Static Single Assignment) 和控制依赖, 将被测程序转化成一个约束系统, 然后寻找经过给定语句的路径, 生成相应的测试数据。基于程序实际执行的测试数据生成方法, 在程序执行的每一步中数组下标、指针值都是确定的。因此, 针对数组、指针处理不存在困难, 但其测试数据生成与路径选择有关, 而判定所选路径是否为可行路径也是一件非常困难的事情。

H o w d e n认为程序错误分为:计算错误 (Computation error) 、丢失路径错误 (Missing path error) 和域差错 (Domain error) 。对于某一特定输入, 程序执行的是正确的路径, 但由于赋值语句的错误而导致输出结果不正确, 这样的错误称为计算错误。由于程序某处少了一个判定谓词而引起的错误称为丢失路径错误。由于程序控制流错误, 而导致某一特定输入执行了一条错误路经, 这种错误称为域错误。对大多数域错误, H o w d e n认为符号测试和实际数据测试是不可靠的。只有当测试者幸运地从不正确的定义域部分选取一个测试数据时, 实际数据测试才能发现这些错误。针对程序域错误, White、Clarke等专家提出了域测试策略, 以后发展成为一个有效的模块测试方法。

结构测试的测试数据生成方法大多只是单纯利用了控制流信息生成测试数据, 这往往是不够的。数据流测试将数据流信息应用到路径选择中, 并定义了相应的测试覆盖准则。无论哪一种结构测试, 即使其覆盖率达到百分之百, 也不能保证把所有隐藏的程序缺陷都揭露出来。

3 基于功能的测试用例生成技术

目前, 关于功能测试测试数据生成的研究主要有:T s a i等提出的从关系代数查询表示的规格说明中生成测试数据的方法。该方法针对关系代数查询表示的规格说明设计测试用例, 因而只适合于数据库和数据处理系统。W e y u k e r等提出的基于布尔规格说明的测试数据生成方法, 该方法将L o v e s o n等的基于过程控制的形式化规格说明方法进行了改进, 用A N D/O R表来描述规格说明中的条件, 因此, 该方法只适合于过程控制系统。随着需求的形式化描述方法的应用, 基于形式化规约的测试研究也得以展开, 就测试用例生成取得了相当多的成果, 但这些方法要求测试人员具有很高的素质和专业水平, 尤其对于大型系统的形式化描述本身就存在困难。

接口测试是功能测试的主要任务之一。基于接口参数的黑箱测试用例选择方法是对系统每个接口参数采用边际值分析法和等价类划分法等选取一组典型的值, 然后在这些取值组合中随机选取一组测试用例, 或者使用一些启发式方法从中进行筛选。但这些方法的缺点是带有主观倾向性, 不具有普遍性。组合覆盖是一种重要的接口参数测试方法。这种方法充分考虑了系统中各种因素以及因素间相互作用可能产生的影响, 可以根据实际需要, 用尽可能少的测试数据尽可能多地覆盖一些影响系统的因素。同时, 这些不完全测试的结果能够反映完全测试的内在规律, 具有代表性。这种方法对于由系统中某些因素相互作用而导致的软件故障具有较强的检测能力。

根据覆盖程度的不同, 组合覆盖方法可以区分为单因素覆盖、两两组合覆盖、三三组合覆盖等。目前, 两两组合覆盖方法已经在软件测试领域得到了成功的应用。人们应用这种方法对软件系统进行测试时, 发现了很多传统测试方法难以发现的错误。其中, 两两组合覆盖的测试数据生成一直是人们研究的重要课题, 至今还没有得到很好的解决。

4 面向对象的测试及测试用例生成

1989年, Fiedler从面向对象的测试与传统测试的差异出发, 提出了面向对象单元测试的解决方案, 拉开了面向对象软件测试的研究序幕。

面向对象的测试通常根据程序的内部结构和形式规范自动或者半自动地生成测试用例, 相应的测试用例生成方法分为基于外部行为的生成方法和基于内部结构的生成方法。基于外部行为的测试用例生成主要是根据类的接口规范构造测试用例, 一般采用代数规范或者基于模型规范来描述被测类的外部接口。

Tsai等应用反向工程, 根据程序源代码获取相应的状态图, 用状态机测试方法执行功能测试, 以遍历所有的状态转移;同时使用数据流覆盖准则来测试类的数据成员, 保证它们满足数据流覆盖。由于采用数据流测试和状态机测试技术, 这种方法可以发现类的成员函数和数据成员内的错误, 但不能发现额外状态。

陈火炎教授等提出了一种黑盒和白盒相结合的面向对象测试的集成方法论。该方法采用黑盒技术用来选择测试用例, 白盒技术主要用来判断从执行测试用例得到的两个对象是否可见性等价, 在某些情况下也用它来选择测试用例。还进一步改进和完善了D o o n g和F r a n k l的A S T O O T工具的方法, 详细论证了他们在将非等价基项作为测试用例的方法和断言中所存在的重大问题, 提出了基于代数规格说明并利用状态转换图产生非等价对作为测试用例的一种新方法, 然后通过白盒技术来确定运行这样的测试用例得到的对象是否可见性等价, 并补充一些测试用例, 对类进行测试。

摘要:从世上第一行程序代码被编制出来, 实际上软件测试问题就已经出现了。随着软件复杂度的增加, 软件测试的重要性逐渐引起了人们的重视。本文正是基于此, 阐述了计算机软件测试技术的发展现状, 旨在为相关领域的研究提供方向性的指导和借鉴。

关键词:计算机,软件测试,概述

参考文献

[1] 王红峰.软件测试风险的分析与对策[J].中国金融电脑, 2009, 2.

[2] 钱超.软件性能测试的流程探析[J].中国金融电脑, 2009, 2.

[3] 金松.软件测试的关键技术[N].湖北三峡职业技术学院学报, 2006, 1.

上一篇:刺梨产业价值链提升研究——以贵州省为例下一篇:坚持以人为本,促进高校和谐校园建设