介绍
在软件生命周期中,软件经常发生变化,软件开发人员任何代码改动都会有引入故障的风险)。为了消除或减小这种风险,在软件迭代开发模式下,回归测试扮演着重要的角色:它能够帮助测试人员验证新增的功能或故障修复后的程序是否满足期望。目前,常见的具有代表性的回归测试策略主要有两种:
- 一是重试所有策略,即选择所有已有用例进行测试;
- 二是最小选择策略,即选取具有代表性的测试用例进行测试。
重试所有策略最大限度地扩大了测试覆盖范围,可以保证在程序修改后原来正确工作的代码不会产生新的错误。但是,随着软件功能的丰富、开发代码的增加,测试用例也随之增多。当测试用例积累非常多时(比如成千上万条),此时一个新功能开发或故障修复完成后进行回归测试,则会对时间和资源的需求量提出巨大的要求。由于测试资源和时间的限制,如果运行全部存量测试用例和开发新的测试用例进行回归测试,显得不太可取。最小选择策略可以缩减测试用例集的大小,测试成本较小,但是检错代码错误的能力相对于重试所有策略则削弱很多。最小选择策略的检测错误能力不够完善,但其低成本优越性,使得无数人员争相研究和推进,它已经成为回归测试中最常用的测试策略。回归上述提及的回归测试策略不难发现,在回归测试活动中,测试用例的选择往往着重于已有测试用例的选择,对于新增功能或功能变动引起的新增测试用例并未提及,而这一部分在回归测试中也占据着重要地位。因此,在有限的时间和资源条件下,如何筛选存量测试用例和设计新增用例,快速地完成回归测试成为了大多数测试人员思考的问题。本文旨在提出一种快速回归测试用例选择方法,帮助测试人员能够快速地完成回归测试。该策略主要涉及两个环节:
- 存量测试用例的筛选
- 新增用例的设计方法
在存量测试用例筛选环节引入相关性判断,考虑测试用例与功能的相关性、测试用例执行通过率、测试用例的稳定性、测试用例的发现的故障数、测试用例的自动化率等几个方面。在新增用例设计环节,引入探索式测试方法(包括局部探索式方法和全局探索式方法)设计新增用例。** 相关工作 回归测试可被分为两类:递进型回归测试和修正型回归测试。递进型回归测试是指对原有测试用例进行修改,以适配测试修改后的程序(如新需求引入导致的模块或功能增删)。修正型回归测试与递进型回归测试相反,主要特点在于原有测试用例不做任何修改。修正型回归测试主要用于修正程序设计错误或缺陷修复后的测试,其目的在于验证程序严格按照测试用例的输入输出描述运行。在软件开发周期内,递进型回归测试和修正型回归测试活动往往是一起进行的。随着软件开发的深入、功能的不断增多,测试用例数量也会不断增大。此时,在成百上千或上万条测试用例的情况下,在某个开发周期内进行递进型回归测试和修正型回归测试,存量测试用例的选择、新功能测试用例的设计和开发都会成为有限时间和资源下快速完成回归测试的瓶颈。传统的全部运行存量测试用例进行回归测试的方法,虽然可以保证测试的高覆盖率,但是会消耗大量的时间和资源,尤其是手工用例居多的时候。鉴于此种情形,如何使用最小选择策略去除回归测试用例冗余性,获取代表性用例进行回归测试,成为了很多学者探讨的问题。最小测试用例集的选择方法有如:基于数据挖掘技术的测试用例选择方法、基于优先级排序的测试用例选择方法、基于启发式模型的测试用例选择方法等等。这些技术为回归测试存量测试用例的选择提供了有效的指导方法,但是它们有的仅是从设计过程选择用例或从执行结果选择用例,未充分考量选取测试用例的全面性。且针对迭代周期内当新增功能或代码变更时,并未提及如何设计新增用例并将新增用例纳入回归测试范围。本文提出的快速回归测试策略重点在于存量测试用例的选取和新增测试用例的设计环节。**考虑到回归测试类型的差异性:
- 针对递进型回归测试,测试用例主要为新增测试用例,新增测试用例的设计方法采用探索性测试方法;
- 针对修正型回归测试,测试用例包含存量测用例和新增测试用例。
在存量测试用例选择时,从用例设计过程和执行结果两个方面出发进行联合筛选。
- 从用例设计过程出发,考量用例与功能的相关性(直接相关、间接相关),选择相关性强的用例;
- 从用例执行结果出发,选择稳定性差、通过率低、故障率低和自动化率低的测试用例。
回归测试用例的选择方法
前面已经说过,修正型回归测试和递进型回归测试在软件开发周期中并不是单独存在和单独进行的。因此,忽视回归测试类型的差异,回归测试用例的选择可以直接略为存量用例的选择和新增用例的设计。
1.存量用例的选择
存量用例的选择可以从用例设计过程和用例执行结果两方面出发考虑,如图1所示。
- 如何从用例设计过程和用例执行结果选择存量用例?
用例设计过程和用例执行在测试活动中是具有先后顺序的,因此在回归测试用例选择过程中,从用例设计过程和用例执行结果选择测试用例也应该具有顺序性。首先,通过用例设计过程初步匹配筛选测试用例,再通过用例执行结果最终锁定可用在当前迭代周期内的存量测试用例。假设:原始测试用例集S0={T1,T2,T3……T1000},测试用例集S0通过“用例设计过程“筛选后的测试用例集S1={ T1,T2,T3……T800},此时将S1输入用”例执行结果“进行筛选,保留的测试用例集S2={ T1,T2,T3……T600}。存量测试用例通过用例设计过程和用例执行结果两步筛选的示意图如下图2所示。
- 如何通过“用例设计过程“筛选存量测试用例?
在该部分,本文提出从测试用例与待测功能相关性两方面进行联合筛选。考虑测试用例与待测功能的直接相关性(直接单功能相关性),和间接相关性(交互功能相关性和质量波相关性)。那么,具体应该如何度量测试用例与待测功能的直接相关性和间接相关性呢?如果一个用例关联的功能发生了代码变更(如故障修复导致),则可定义该用例与该功能的直接相关性强。若此时该功能纳入回归测试列表,则该功能直接关联的用例也应该进入回归测试用例列表;如果一个用例并未与待测功能直接相关(如该用例关联的功能代码并未改动),但待测功能代码发生的变更会波及该用例关联的功能代码(如接口变更波及),则该用例也应该进入回归测试用例列表;又或者待测功能代码的变更导致其他功能模块的质量属性发生变化(如中间组件切换导致软件性能发生改变),则与该质量属性相关的用例也应该进入回归测试列表。
- 如何通过“用例执行结果“筛选存量测试用例?
本文主要从用例执行的稳定性、通过率、发现故障数和是否自动化四个方面进行分析。
- 稳定性指的是一定时间内,用例多次执行结果相同的概率(如执行10次,10次执行结果都是pass或fail,则称该执行结果稳定;反之若pass和fail反复交替出现,则该执行结果不稳定)。
- 通过率指的是一定时间内某个用例总的执行次数中,通过次数的占比,可以用公式表示为Pr=(result passed numbers/execution total numbers*100%)。
- 发现故障数顾名思义就是执行该用例发现的故障数。
- 是否自动化指的是该用例是自动化用例还是非自动化用例。
用例稳定性强弱可以体现用例设计的质量高低,稳定性越弱则代表该用例可能属于低质量用例,设计存在不合理之处;用例通过率越高则证明用例关联的功能越稳定,用例设计的质量也高。发现故障数可以从侧面反映用例的有效性,若一个用例发现的故障数远大于其他用例,则证明该用例的有效性强,相较于其他用例能够发现更多的故障。是否自动化不是一个硬性指标,但可以帮助测试人员进行回归测试时节省时间和资源。设想:如果一个用例在一定时间内执行X次执行结果稳定性差,反复pass和fail(假设各X/2次,X为偶数),执行通过率低(假设小于等于50%定义为通过率低),发现故障数多(假设相较于其他用例,发现故障数大于N定义为发现故障数多),且该用例未能实现自动化,那么存在的这样一个用例在”用例执行结果“筛选环节应该被保留,成为进入当前迭代周期内的存量测试用例。通过“用例设计过程“和”用例执行结果“筛选存量测试用例的具体参考指标和筛选示意图如下图3所示。
2.新增用例的设计
较于传统脚本式测试方法,探索式软件测试方法可以帮助测试人员更好地、快速地检测软件功能中的错误。在James A.Whittaker的《Exploratory Software Testing》一书中,提到了两种探索式软件测试方法,即局部探索式测试法和全局探索式测试法。对于修正型回归测试和递进型回归测试中新增用的设计,本文选用局部探索式测试方法和全局探索式测试方法进行分层用例设计。假设:新增测试用例集为S3,则S3包括局部探索式测试方法设计的测试用例集ΔS3_1和全局探索式测试方法设计的测试用例集ΔS3_2,可用公式表示为S3=ΔS3_1+ΔS3_2。探索式测试方法设计新增用例示意图如下图4所示。
- 如何运用局部探索式测试方法进行新增用例设计?
局部修正型回归测试往往是由故障修复、功能细节变更引发,代码层面不会发生较大的变化。因此,在修正型回归测试中,针对局部功能变化或代码变更引入的新增测试用例,可以从代码角度(如:代码函数变更、代码文件变化)出发进行用例设计。比对代码变更部分,使用局部探索式测试方法从用户输入数据、代码路径、软件内外部状态三个方面着手进行探索式测试用例设计。
如:检测用户输入数据的类型和值范围,测试当用户输入数据类型与设定的类型不一致或输入值越界时软件的反应;
如:针对某部分代码或文件,进行非常规代码路径测试,观察软件的反应;
如:模拟异常输入行为造成内部状态异常时的软件反应。
如何运用全局探索式测试方法进行新增用例设计?
全局探索式测试方法重点关注软件的整体功能和质量属性,针对递进型回归测试和修正型回归测试中新增功能或功能变更部分,运用全局探索式方法中的:
- “卖点测试法”测试软件核心功能;
- “上一版本测试法”测试软件兼容性;
- “恶邻测试法”测试软件功能波及性;
- “通宵测试法”测试软件稳定性等方面。
如:长时间运行软件,测试软件功能是否稳定。使用探索式软件测试方法的新增用例后,回归测试用例此时已经包括筛选后的存量测试用例和新增的测试用例。通过“用例设计过程“、”用例执行结果“和”探索式测试方法“产生最终测试用例集的示意图如下图5所示。
回归测试用例的选择方法的意义
1.与用例分层的关系
从前面章节可以看出,在回归测试活动中,筛选存量测试用例其中的“用例设计过程“,从关联功能出发,以两个方向三个维度进行用例筛选。两个方向分别是:用例与待测功能的直接相关性,用例与待测功能的间接相关性。三个维度是对两个方向的细化,分别是:单功能相关性、交互功能相关性和质量属性相关性。这三个维度从传统测试分层来看,可以FT和ST相对应。此外,使用局部探索式测试方法进行新增测试用例设计时,重点在于关注代码层的变化,如代码函数变更、代码文件变化,基于此进行的代码路径测试和用户输入数据测试类似传统测试分层中的UT测试,用户输入数据和软件内外部状态测试类似传统测试分层中的FT测试。使用全局探索性测试方法设计新增测试用例时,相应的测试方法和测试要点也可以与测试分层结合。如:卖点测试法的软件核心功能测试,上一版本测试法的软件兼容性测试可以对应传统测试分层的FT和ST测试。从测试分层的角度进行存量测试用例的筛选和测试用例的规划与执行,可以提高测试用例执行的效率,节省资源消耗。回归测试用例筛选存量用例和新增用例的过程和方法与测试分层的对应关系如下图6所示。图6回归测试用例筛选和新增过程与方法与测试分层关系示意图
2.与用例生命周期的关系
本文提出的回归测试用例存量用例的筛选方法,结合测试用例的生命周期过程中的“用例设计过程“与”用例执行结果“两大环节进行测试用例的筛选,在删减冗余测试用例的同时,提高了用例筛选的全面性和有效性。** 总结 **本文简单阐述了回归测试的重要性和类别,提出了针对大量存量测试用例,如何筛选存量测试用例、去除用例冗余性、选择代表性测试用例加入回归测试的方法。同时阐述了针对回归测试中的新增功能或修正功能部分,如何运行探索式测试方法设计新增测试用例。此外,还从用例分层和用例生命周期的角度说明了本文所述方法的优势和意义。