在软件生命周期过程中,不同测试阶段、不同测试目的、不同测试类型,测试目标不同且不断变化,测试策略亦随之演进和迭代。基于质量、效率、能力驱动,构建多维度测试策略监视与测量体系及反馈机制,对测试目标、测试类型、测试阶段、约束条件及质量风险等变化进行监视和测量,对测试过程活动的变化及过程偏差、质量风险等进行分析,确定偏离结果及导致偏离的主要因素,将监视测量结果反馈到测试过程,对测试策略及测试组织、资源配置、测试流程等进行动态调整,持续改进测试过程,实现组织效能提升和质效平衡。软件测试策略监测与控制如图4-25所示。
图4-25 软件测试策略监测与控制
在软件生命周期过程中,任一阶段的过程活动都不可避免地会引入不确定性,不确定性是软件生命周期过程的固有属性。不确定性依赖于不同阶段的工作产品,每个元素的开发过程模型、工作产品、运行环境、使用场景等各不相同,而人的介入进一步引发了预期结果的变化。随着系统需求工程、设计开发等工作的推进,不确定性逐渐增长。我们希望所有不确定性能够得以有效识别、标识、度量和管理,能够无缝、稳定地适应不同需求。
一般地,不确定性有两个来源:对问题域、用户需求的理解偏差及维护不够。不确定性可分为两类:一类是验证给定需求是否属于系统规格,在不能确定需求规格正确性的情况下,软件开发没有任何意义,是需求测试与确认的基础;另一类与有效规格说明的生存周期有关。
通常,可以通过拟合曲线、案例分析、边际效应等方法对不确定性进行度量,基于工作产品、过程活动等不确定性的概率表述,采用模糊化、专家系统、神经网络、可能性推理等进行不确定性建模。首先,识别并确定不确定性来源,如果测试结果未能达到预期目标,或超出预期的概率区间,则对这种不确定性进行标识,如果能够准确地识别不确定性,就可以有效实施软件风险管理。其次,分析产生不确定性的场景,有针对性地采取措施,举一反三整改。与此同时,制定并持续完善不确定性预防机制,对不确定性进行预防和控制。
用一个三元组[ I , S , O ] 表示一个测试用例。其中, I 表示输入数据; S 表示系统的状态,即每个阶段结束后产生的工作产品; O 表示系统输出。对于给定的有限输入空间 I 、输出空间 O 及将输入映射到输出的函数 f (i),测试用例定义如下。
【定义4-1】 测试用例( I , S , O ) :对于 I 中的所有 i ,存在 f ( i )= r , r ∈ O 。
测试用例集构成测试套,每个测试用例的预期输出已知。如果系统输出是预期输出,则称被测系统的状态是确定的。
【定义4-2】 确定性( I , S , O ) :对于 I 中的一个 i ,且 o ∈ O ,有 f ( i )= o 。
如果预期输出未知,但输出分布已知,则存在风险。对于给定输入 i ,系统输出未知,但知道落在输出空间一定的分布范围。
【定义4-3】 风险 :存在于 I 中的一个 i ,使得 , 。
如果输出及分布均未知,存在不确定性。不确定性的概率已知且风险可评估,但不确定性中的任何意外事件的发生概率都是不可计算的。对于给定输入,所产生的输出落在输出空间之外,导致不确定性。如果对于同一输入所产生的输出不同,同样也会产生不确定性。
【定义4-4】 不确定性( I , S , O ) :存在于 I 中的一个 i ,使得 f ( i )= p , 。
问题域、软件需求、体系结构、解决方案域、人员介入、需求变更、赛博物理系统、移动性、快速演化及学习等无一不是导致不确定性的重要因素。
问题域中最常见的不确定性源自软件需求。首先,软件系统是对现实世界问题的建模,而现实世界本身就存在着不确定性,对其建模的系统自然地继承了其不确定性。其次,基于模型构建系统,需要对用户需求进行准确识别和理解,将用户需求转换为软件需求并映射到开发模型的过程,同样会导入不确定性,并且对用户要求的近似处理也可能产生不确定性,何况用户需求及优先级本身就存在着不确定性。再次,对于软件需求中的问题假设、约束条件,需要进行假设检验和模型一致性验证,否则可能导致风险和不确定性。最后,模型结构会因各种因素和数据集合的动态变化而变化,依据历史数据构建的模型可能带来不确定性。
对于特定问题,可能存在多种体系结构选项。如果不同选项的后果未知或不确定,固化系统体系结构时,无疑会引入不确定性。不同的解决方案,可能产生不同的结果,也可能带来不确定性。测试策略的不确定性则会带来整个测试过程的不确定性及不确定性的蔓延和放大。
软件测试是人员密集型活动,人的因素占据着支配地位,除非实施全自动化测试或标准作业过程,否则势必引入不确定性。非正常的操作使用,非理性的需求变更,也是导致不确定性产生的重要原因之一。软件开发是一个持续迭代的演化过程,软件需求持续变更。如果需求规格是公理性的,且通过有效性验证和确认,则认为公理性需求规格是确定的。非公理性需求规格可能发生变化。基于持续不断的变化,如果需求规格没有得到同步验证和确认,其有效性将无法得到保证。对于这类不确定性问题,需要在整个软件生命周期过程中,对非公理性需求的有效性进行周期性评估和确认。
赛博物理系统的实现需要在软件和实体要素之间进行复杂的转化和迭代。对于大型复杂系统具有的不确定性,可能很难获得实体环境的动态观察,且系统构成要素行为观察的不完整性进一步加剧了对系统运行不确定性的理解。移动应用的部署方式与从简单的桌面系统到复杂的云计算环境,需要部署大量不同移动终端,可用资源差别很大,且具有很强的动态性。因此,移动应用的输出对于特定的目标环境可能是不确定的。
软件测试的不确定性问题非常突出,但却未得到足够重视。例如,外部软硬件带来的不确定性,被测系统在模拟环境和真实环境下输出的差异性和不确定性,不同测试人员、不同测试方法、不同执行顺序、同步性及其他动态问题等导致测试结果的差异性和不确定性,测试环境失效带来的不确定性,等等。假定软件生命周期过程中,下一阶段的工作是在上一阶段工作正确输出的基础上进行的。但由于输入及过程活动中的不确定性,难以保证相应输出的正确性,并且随着软件开发的演进,不确定性不断积累,设计输出产品的顺序和执行逻辑会受到不确定性因素的影响。为了开发高质量的软件系统,必须对软件生命周期过程中不同阶段的工作产品进行测试、验证和确认,降低阶段活动及阶段工作产品的不确定性。
在测试策划过程中,基于系统特征、系统行为、约束条件、测试风险分析,制定不确定性控制策略。目前,一种行之有效的方法就是制定精准的测试准则,用于确定系统行为是否为预期正确行为。由于不确定性的存在,测试人员或测试团队可能难以预先判断测试用例执行输出,宽松的测试准则有可能影响缺陷定位。测试准则由准则信息和准则过程两部分构成,准则信息定义正确行为的条件或状态,准则过程用于验证测试执行所对应的指定准则。基于形式化规格说明的准则,能够保证规格说明提供的意向行为的正确性。
理论上,只有穷尽测试才能确保测试的充分性,有限的测试用例可能无法覆盖所有测试需求,由此引入不确定性,并且测试用例绑定也会带来不确定性。因此,测试用例选择及适合性确认、正确性检查至关重要。所谓测试用例的适合性是指能够恰当地验证软件质量的程度,取决于多种因素,对测试用例适合性理解得不深入会造成测试用例分类的不确定性。目前,软件测试用例适合性度量尚存较大困难。如果测试用例的正确性未经验证,测试结果可能存在着不确定性。对测试用例集的确认主要考虑所执行测试用例集的适合性及价值,测试用例集可能存在冗余性、模糊性和不适合性,会显著增加测试工作量。
软件测试是由错误检出和错误纠正两个阶段构成的周期性过程活动。对于相同的开发环境及输入,每次测试可能执行不同路径,重复执行某个场景并无实际意义,因为有可能存在不同场景并发存在的情况。并发性增加了并行程序的复杂性,并行程序测试所需工作量较顺序程序大得多。在某些情况下,同样的输入,对于并发或并行程序并不能得到同样的输出。例如,第一个过程试图在一块共享内存中执行写操作,而第二个过程从同一块内存读取数据,因为过程所要求的新、旧值会产生差异,第二个过程的输出不同于第一个过程。如果类似输入导致不期望的行为或不可接受的输出,系统就可能无法创建该错误场景。这种情况被称为海森堡不确定性原理,即“观察者的存在可能影响科学观察,使得不能确保所得到的观察结果是真实的”,此乃所谓探针效应。如果不存在同步错误就可能不会发生探针效应。并发程序设计中的不确定性是由于竞争条件引起的,该问题的处理取决于网络负载或CPU负载等因素。