王 东
(广东白云学院大数据与计算机学院, 广州 510450)
在软件工程领域中,软件质量实际上是一个多维的概念。其中,软件可测试性是软件质量保证体系中的重要内容,它可直接反映出软件测试工作的复杂性和工作量。在软件设计和开发过程中,增强可测性亦可增加软件测试过程中发现缺陷的概率。ISO/IEC 9126-1 标准定义的可测性是指:对修改后的软件进行测试的能力。ISO/IEC 25010:2011 系统和软件工程标准定义的系统和软件质量需求和评估标准(SQuaRE)中的软件系统质量模型将可测性作为可维护性的一部分。
可测试性从另一方面也可反映出是对软件进行测试工作的便利程度,其本身就是一种质量属性。测试是软件开发过程中评估软件质量的活动,需要专业的方法和工具。测试工作包括方方面面,主要有:功能、性能、安全性、易用性等测试。目前,自动化测试虽能提高效率、降低成本,但在相当长的一段时间内尚不能实现对人工手动测试的替代。
当一个软件具有较高可测性时,在相同的测试强度下,软件测试人员更容易发现软件缺陷,也可以说发现更多软件缺陷;而当软件的可测性较低时,软件系统中的缺陷将不易被发现,测试工作量也将随之上升。由此可见,软件的可测性将影响软件测试成本,进而影响软件质量。
影响可测性的五个主要因素有:可理解性、可观察性、可控性、可追溯性和对测试的支持能力。本文所述的对软件可测性和测试用例有效性的研究问题为:静态代码和测试度量对测试用例有效性和可测性的影响。
可测试性是软件质量模型的重要内容之一,对可测试性的度量工作因影响因素较多而具有较高难度。低可测试性的软件系统具有较低的可靠度,这与测试工作的严密性无关,而且低可测性的软件系统往往在软件开发后期的维护和更新成本更高,更难控制。软件系统的可测试性关系到软件的可靠性、测试效率、测试成本和工作量。对于软件开发而言,测试的成本占整个软件开发成本的50%甚至更高,因此改进可测试性对提高测试效率和降低整体开发成本有着重大影响。理想状态下,测试人员在设计和执行测试用例所花费的时间应该占到全部开发时间的25%~50%之间。当前热门道德软件开发方法,如:敏捷方法、极限编程和Scrum迭代式增量软件开发方法等,均体现出了测试工作的重要性。以测试驱动开发(TDD)为例,为确保软件系统存诸单元的可靠性,TDD 在编写代码前已由开发人员或测试人员完成设计和开发测试的工作[1]。单元测试是提高软件质量的主要方式,可开发过程的早期阶段发现和低成本修复bug。在实际生产环境中,测试代码量与软件开发代码量的比例约为1∶1。
总之,提高软件可测试性对提升软件系统的质量有着积极作用。但是,对软件可测试性的度量和评估工作具有一定的复杂性。
IEEE 定义的软件可测试性(software testability)是指一个软件工件(软件系统、模组、需求文件或设计文件等)在一个给定的测试环境下,可支援测试的程度。ISO标准将可测试性描述为“与验证软件产品所需工作有关的软件属性”。因此,ISO从测试软件产品所需工作的角度出发定义了可测试性,而IEEE 从测试标准的角度定义了可测试性[2]。
McCall 质量模型是第一个定义软件质量的质量模型。McCall 模型的主要内容包括:便捷性、仪器和模块的可测试性,并将其定义为验证需求的能力。Boehm 改进了McCall 模型,将可测试性定义为验证需求是否满足实现的软件的便捷性。ISO9126质量模型定义可测试性为验证软件产品所需的必要工作。
在软件工程领域,软件测量的主要目标是帮助软件工程师和项目管理者做出针对软件开发过程的准确的预测和决策,通过监控项目进展并适时介入质量控制机制判断软件项目及其各组件的功能和性能是否符合需求。软件度量是指量化和度量软件特性的指标参数,软件指标是软件质量的重要组成部分,在分析和提高软件质量方面发挥了重要作用。此外,软件指标可用于验证软件质量的要求是否被满足[3]。
软件测试中的软件度量包括:产品、过程和项目度量。而过程和产品度量与软件质量关系密切。过程度量标准反映了开发过程质量,而最终产品度量标准反映了软件产品的特征。根据产品度量系统的不同方面,产品度量可以进一步分为静态度量和动态度量。静态度量在软件非运行状态下进行度量,是对软件的内部质量的描述,大多数现有的质量度量以静态形式出现,如代码行度量和开发复杂度度量。动态度量只能在运行时对软件的属性进行度量,是对软件运行状态的描述。
本研究采用的可测试性数据集源自1186 个大大小小的、不同类别的Java 开源项目[3-6]。数据包含多个不同类的度量(继承、大小、复杂性、内聚性、封装性和耦合性等)、6 个测试工作量度量和3 个测试质量度量。在文献[3-6]中提到了收集数据信息和分析计算指标的工具,本文采用了其中介绍的方法。表1 为本研究所涉及的软件度量类别。
表1 软件度量分类列表
本研究所选实验数据集源自1186 个Java 开源项目的9861 个实例(类)[4]。考虑到本实验的研究重点是测试有效性问题,本研究将突变分值一项作为研究重点。突变分值通过组合测试百分比计算被消除的突变体。除了通过突变分值来评估测试执行中发现缺陷的能力外,这些分值还表示了不同测试活动发现缺陷的能力的差异。突变分值范围为0~1。
本研究根据突变分值将数据结合的测试分为有效和无效两类,利用突变分值四分位数将第1 个四分位数内的测试分配到非四分位数集,而第4 个四分位数内的测试被分配到有效集。任何落在这两个四分位数之间的测试用例都将被丢弃。基于响应离散化噪声的背离分配给特定类的数据点。由于本研究重点在于探索有效测试特征和无效测试特征,因此,为了突出效果的差异,实验去掉了具有平均有效值的测试类。
在计算该数据集的四分位数后,研究发现突变分数为1 的测试用例被认为是第4 个四分位数的一部分,0.4 及以下的测试用例被认为是第1 个四分位数的一部分。因为具有平均行,实验删除了其余四分位数中的所有实例。数据集中的其余实例为5022。本研究旨在评估Java面向对象类的测试有效性(可测试性)。
以突变得分作为因变量,即被消除的突变体除以产生的突变体数量的百分比,因变量也是开发人员使用的可测性关键指标之一。自变量除了两个主要维度(测试工作量和代码度量)外,还考虑了34 个因素(见表1)。这些度量为测试人员提供了验证测试是否具有有效性以及是否与这些元素相关联[5]。本研究目标之一是确定仅依赖于静态代码质量特征的轻量级估计模型,这些特征可以很容易地计算到当前版本的测试类。由28个特性组成的代码度量集,用于评估继承、复杂性、耦合、大小、封装和内聚的效果。对测试类工作量的计算参考了测试用例的复杂性和数量的相关的测试工作量的度量[6]。
本研究的主要目标之一是对影响测试用例有效性(突变分值)的因素进行分析,例如检测缺陷的能力,以便在开发测试用例时将有效性指标更好地付诸实施。为此,本研究设计了三个研究问题。第一个研究问题针对所选的34 个自变量和测试用例有效性之间是否存在关联的初步评估,其目的是揭示具有高或低突变分值的测试用例的自变量分布是否变化以及变化到何种程度;第二个研究问题关于在机器学习技术的基础上制定自动化策略时,如何根据突变的分数来检查测试的有效性;最后一个研究问题是找到最主要的可测性指标是什么。本研究将三个研究问题概括如下:
研究问题1:静态度量和测试用例有效性之间有关系吗?
研究问题2:静态代码和测试度量在多大程度上有助于预测测试用例的有效性?
研究问题3:最具影响力的可测试性指标是什么?
针对研究问题1,本研究引入了Spearman的秩相关系数用于评估静态度量和测试用例有效性两个指标的统计依赖性,Spearman 方法准确度高而且不需要正态数据分布[7]。针对研究问题2,有不同的机器学习算法可供选择,由于分类器使用的预测目的可能会对模型的性能产生较大影响,因此在选出最优的估算模型的分类器之前,本研究将对多个分类器分别进行测试。因此,本研究将比较不同机器学习算法的效果来确定可测试性预测模型。
决策树利用高度信息性的特性来划分含有不同类的测试实例。本研究采用了C4.5 决策树版本,它使用了基础信息熵的概念为每个子树选择根节点,决策树是一种易于理解和解释的分类器[8]。
随机森林其实是一种协作学习方法,其可在引导数据上创建决策树的多元变量。随机森林中的每棵树都是基于真实数据的子集上构建的,并在一个高鲁棒性的分类器中展示特征结果,一个预测类的选出将取决于选票数量。随机森林的开箱即用的便捷性能是一大特色[9]。
多层感知器是一种嵌入在深层架构中的前馈神经网络,该架构包括在有向无环图中相互连接的不同计算单元层,他们具有将输入映射到输出的特性,并且在回归测试项目中采用较多[10]。
为区分不同的类标签,本研究中的静态指标排名根据它们的贡献来判定,排名算法采用预分配的一个分数来评估单个特征,并根据该分数对它们进行排名。针对研究问题3,本研究采用了四种不同的算法来分析对可测性影响最大的指标,即增益比、信息增益、对称不确定性和OneR算法[11]。
本研究采用了Spearman 等级相关系数并对实验结果进行分析,出于验证测试有效性的目的,本实验结果只包含系数达到0.5以上的正相关或负相关的结果。表2 显示的相关值反映出大小和耦合与突变分值呈高度负相关。针对研究问题1 的答案可以得出:有效测试用例与被测类的复杂性和大小度量之间存在明显的负相关关系,也就是说,减少类的大小并降低类的复杂性将增加类的可测试性。
表2 带有突变分数的静态度量的Spearman相关系数
针对研究问题2,探究静态代码和测试度量在多大程度上能够影响对测试用例有效性的预测精准度。表3 反映了所选分类器在五个评价标准下的性能。如上所述,使用测试指标和静态代码的模型不仅依赖于F测量(87%),并且在AUC 分析期间也表现出了较高性能。三个选定的分类器中,随机森林机制在所有五个评价标准上得分最高。实验结果表明,机器学习方法可有效评估测试用例的有效性。本实验选择了多个领域的测试项目,实验结果证明本评估模型对于测试用例有效性的评估是有效的。
表3 预测模型的分类结果
针对研究问题3,未找到对可测试性影响最大的因素,本实验比较了不同的排名算法。表4显示了不同排名算法的重要度量,这些度量是针对度量类可测试性的易用指标。表4 反映出表内所有算法都能找到排名靠前的指标。这些重要的指标包括:NBI、RFC、LOC、LOCCOM、WMC 和NMC。为深入研究这些指标,本研究通过对这些指标进行分类来设计属性。字节码指令 数(NBI)、代 码 行 数(LOC)、注 释 行 数(LOCCOM)和方法调用数(NMC)是代码量大小的度量。而对一个类的响应(RFC)和每个类的加权方法(WMC)被认为是复杂度度量。这表明,在软件开发过程中,为确保系统可测试性,需要观察和监视这些度量值。
表4 使用不同排名算法的重要度量
本研究通过实验证明了源代码质量在解决测试用例有效性方面的作用,软件测试人员参考本研究成果可有效避免无效测试的发生。软件开发人员在软件设计和开发过程中参看本研究提出的模型可从设计和编码阶段的源头避免无效测试情况的出现。
本研究推荐的评估模型可检查测试过程中的质量。对于开发人员来说,通过突变测试方法来评估测试有效性问题能够做到更精准和更高效,这种方法可帮助测试人员分析找出影响精准高效测试的负面原因。通过对测试代码有效性的初步评估可帮助测试人员理解影响测试有效性的主要因素。
本研究分析了测试指标和静态代码方面的28 个因素与测试用例有效性和可测试性之间的关系。通过建立预测模型,利用已知因素区分无效测试和有效测试。此外,还阐明了相关的基本代码度量对面向对象类的可测试性的影响。本研究还将在未来通过进一步的实验,探索更多其它的度量因素对测试用例有效性的影响,例如:对面向过程类应用的测试,并将研究成果应用于测试过程中,如:测试用例的设计与选择、优先级划分和自动化测试。