面向适航标准的机载软件测试验证方法综述
2021-08-06谭莉娟刘友林杨丰玉
谭莉娟,郑 巍,刘友林,樊 鑫,杨丰玉
1.南昌航空大学 软件学院,南昌 330063
2.南昌航空大学 软件测评中心,南昌 330063
机载嵌入式软件,就是指安装在以应用软件为中心、计算机技术为基础,由软硬件模块组成能够独立运行的可裁剪的航空电子系统中,作为核心控制作用的计算机应用软件部分[1-2],例如飞行控制系统软件、通信导航系统软件等。机载嵌入式系统中许多关键的功能都是由软件支持的,随着软件技术在航空领域的广泛应用,影响机载嵌入式系统的软件因素从3%增长到了80%[3]。机载嵌入式软件的实时性、高可靠性是航空电子系统正常运行的重要因素。据统计,60%的机载电子设备故障问题来自于软件缺陷,并且造成了巨大损失。例如,2004年12月,美国第四代战机F-22起飞时机载制氧系统存在严重缺陷而失控发生了坠毁事故,导致该型战机全部被迫停飞。因此,确保机载软件质量可靠性的关键工作就是对航空机载嵌入式软件进行测试。
由于嵌入式软件的特殊性及复杂性,目前嵌入式软件测试技术研究进展落后于普通的软件测试技术。自20 世纪70 年代开始,国外开始研究嵌入式软件测试方法,研究人员试图用专门的软件测试技术对单嵌入式软件系统进行测试。1980年Glass的一篇关于嵌入式软件测试技术的文章Real-Time:The“Lost World”of Software Debugging and Testing[4],得出了嵌入式实时软件测试的进展明显滞后于一般软件测试的现状,并针对性地提出了相应的解决方法。之后许多研究机构针对嵌入式软件的特性进行更深入地测试研究,对嵌入式软件测试的方法研究进度不明显,转而开发支持嵌入式软件测试工具,例如AMC公司开发的嵌入式实时分析测试工具CodeTEST,推动了嵌入式软件测试自动化的研究进展。我国从20世纪90年代才开始从国防电子领域展开对嵌入式软件测试的研究,与国外研究水平差距较大,针对性地开发了软件测试工具,例如北京航天航空大学为测试C 语言环境下的嵌入式软件系统开发了SafePro/C测试软件,航天204所为测试嵌入式汇编语言开发了ATEST 测试工具[5]。嵌入式软件在航空航天机载系统中的比重逐渐增加,其质量严重影响着系统的运转,受到相关研发部门的重视,但是国内对嵌入式软件测试理论、技术及工具的研究仍处于初步阶段,需要后续进行大量研究学习,可借鉴面向适航标准的机载软件测试验证工具综述,是针对机载软件测试验证的工具进行的总结,侧重点不同。
在部署之前,机载嵌入式软件必须经过航空航天认证机构的审核和批准。DO-178C[6]标准是2011 年由美国RTCA 提出的国际民用航空行业内及局方遵循的标准,为了满足适航认证审定的标准,定义了软件生存周期过程中的活动和目标,对机载软件生存过程提出了一系列要求,软件验证过程为机载软件整个生存周期质量提供了可靠保证。基于DO-178C的软件测试是对软件开发过程的验证过程,主要目的是证明软件是否满足需求,并以高置信度证明可能导致其在系统安全性评估过程中确定为不可接受的失效状态的错误已被消除。
为了确保机载软件系统的安全保障,适航是对载人航空器飞行的最低安全性要求[7],因此相关管理部门进行了大量的研究与实践工作,颁布越来越完善的机载软件适航标准体系。1982年,DO-178标准第一版发布,为开发机载软件提供基本信息;随之1985 年发布了关注需求的验证和确认的DO-178A;1992 年美国航空无线电技术委员会(Radio Technical Commission for Aeronautics,RTCA)为支持数字计算机的机载系统和设备的研究工作提出的《机载系统和设备合格审查中软件方面的考虑》(DO-178B[8]),DO-178B规定了软件开发和验证的原则,广泛应用于世界民用航空领域的适航审定过程,也是中国民用航空局批准的民用航空机载设备和系统软件的适航审查依据[9]。
然而,随着软件代码复杂性的增加和新开发技术的出现,软件代码开发需要新的验证和认证方法。因此,在2008年,业界和学术界共同建立了一套基于DO-178B的基础上修订的认证标准DO-178C,于2011 年正式发布,增加了对参数数据项的指南以及系列配套补充文档的引用。
DO-178C标准构建了一套基于目标、面向过程的体系。如图1 所示,DO-178C[6]标准把软件生命周期分为软件计划过程、软件开发过程和软件综合过程,针对软件生命周期的每一个过程,定义了具体目标、相关活动和输出。
图1 DO-178C软件生命周期过程Fig.1 DO-178C software life cycle process
软件计划过程定义了软件生命周期、软件开发计划和标准以及系统需求,用于指导软件开发过程和软件综合过程。软件开发过程策划了软件开发的活动过程,分为软件需求过程、软件设计过程、软件编码过程、集成过程。软件综合过程包括审定联络过程、软件验证过程、软件质量保证过程、软件配置管理过程,贯穿软件生存周期全过程,以此保障软件活动过程中输出正确并且受控可信。软件验证过程不仅策划了软件开发过程中的验证过程,还对验证过程的结果进行了验证,即验证的验证,按照软件计划定义的方法和活动对软件需求、软件设计、软件编码和集成的输出以及软件验证进行验证的过程。
软件验证的主要方法包括评审、分析、软件测试。评审和分析适用于软件开发过程和软件验证过程的结果,测试针对软件代码进行动态评估,通过测试用例来运行软件产品以验证代码是否满足需求。当需求无法通过测试用例测试时,可采用评审和分析的方法进行验证。
因此根据DO-178C标准,采用各种验证手段,以验证的结果证明所验证的对象是否满足机载系统适航的要求,贯穿软件生命周期的全过程,对应于图1 中的软件需求过程、软件设计过程、软件编码和集成过程以及软件验证过程,分别从基于需求、基于安全性分析、基于模型以及软件验证的测试四个方面,对软件高层需求、软件体系结构的安全性设计和安全性需求、模型驱动的开发以及软件验证过程输出结果进行测试验证,研究了机载软件测试验证的方法,并对已有工作进行发展前景展望。
1 机载软件测试环境
机载嵌入式软件测试是一种特殊的软件测试,旨在验证发现尽可能多的机载软件缺陷,提高机载软件的可靠性。机载嵌入式软件的实时性、高可靠性、嵌入式等特殊性,再加上其内存不丰富、I/O 通道少、开发和测试环境专门化以及与硬件紧密结合的特点[10],对其开展测试工作相对复杂且困难重重,通常在宿主机环境下开发,目标机环境下运行,而目标机测试环境下严重受到硬件的限制,难以对其进行大规模的嵌入式软件测试,只能在条件允许的情况下通过仿真机测试发现尽可能多的错误并及时改进,这导致测试的工作量和难度大大提升。
嵌入式软件测试环境需要支持交叉开发与测试,如何在开发环境(宿主机环境)和运行环境(目标机环境)之间进行测试数据的交互成为了待解决的主要问题。通过在宿主机上运行测试管理系统和在目标机上运行测试调度软件的方式,来共同完成对机载软件的测试,测试环境支持测试用例的加载,最终记录和分析测试结果。
其中解决通信连接问题的方法就是宿主机和目标机之间建立物理连接,通过串口通信或者以太网口进行基于TCP/IP协议的数据传输。如图2所示,在宿主机方测试,根据测试用例库以及事先制定好的测试计划手动或自动批量加载相应的测试用例并生成测试脚本,通过脚本解释器实时解释非实时生成的测试指令,将测试数据通过目标机服务器发送至目标机;在目标机方测试,引入测试代理接收到指令后运行被测嵌入式软件,将从测试代理获取的测试结果数据进行分析显示,最终生成相应的测试报告[11]。
图2 嵌入式软件测试宿主机与目标机总体系结构Fig.2 Architecture of host and target machine in embedded software test
2 基于需求的测试
DO-178C聚焦于基于需求的测试,对应于软件开发过程中的软件需求过程。根据需要选择某种方式进行某项功能的测试,验证软件需求实现的正确性,以保证需求得到满足并且只有需求得到满足,保证没有非预期的功能。
软件需求测试的目的是验证与系统需求的符合性、准确性和一致性、与目标机的兼容性、可验证性、与标准的符合性以及可追踪性。为了保证需求的质量,航空电子软件采用各种手段进行软件需求验证,包括非正式和正式的软件需求同行评审、需求分析模型自动检查、需求分析模型模拟仿真、需求原型确认和测试。
根据DO-178C的要求、被测软件的重要度等级,确定测试需求,并根据项目实际情况制定详细的测试计划。在计划中需要明确测试要求、测试环境、测试工作过程和内容以及进度和人员安排;然后在计划通过审核后设计测试用例,编写测试说明,并进行审核,审核通过后执行测试并记录测试结果。
2.1 测试方法
如图3所示,DO-178C提出了三种基于需求的测试方法:低层需求的测试、软件集成测试、软件/硬件集成测试。
图3 基于需求的软件测试过程Fig.3 Software testing process based on requirement
(1)低层需求的测试
该测试方法主要测试在宿主机上的软件是否满足低层需求。此方法检查低层的功能,如算法的符合性和准确性、循环操作、逻辑判定、输入状态的条件组合、丢失或失效的输入数据、异常处理、计算顺序等。
(2)软件集成测试
该测试方法主要测试软件组件之间的内部交互关系,以及软件体系结构的需求实现的情况。此方法揭示的典型错误有变量和常量的初始化错误、参数传递错误、数据失效以及不当的事件或操作顺序等。
(3)软件/硬件集成测试
该测试方法主要测试在目标机上的软件是否满足高层需求,使用正常和异常的输入,发现软件在此执行环境中运行时可能出现的问题。通过此方法可以验证的区域包括:中断处理、对软硬件瞬变或失效的软件响应、资源占用问题、自检测、软硬件接口错误、控制回路行为、可加载软件的机制以及软件分区等。
针对测试标准,DO-178C 规定了必须完成的目标,对于A级别软件,DO-178C规定其低级测试需要满足独立性要求。若软硬件集成测试和软件集成测试已经覆盖软件高层需求和软件代码时,则没必要重复进行低层需求的测试。
基于需求的测试过程是递进迭代的过程,通过测试的开发覆盖所有的需求,运行测试覆盖代码并且不断分析,如果有遗漏的需求或者代码,则要增加相应的测试直至所有需求和代码都被覆盖。
2.2 测试用例自动生成
如图3所示,DO-178C提出了三种基于需求的测试方法:低层需求的测试、软件集成测试、软件/硬件集成测试。测试的关键环节是设计和生成有效的测试用例。测试用例是有效发现软件中缺陷的最小执行单元,为满足特定需求目标而编制的一组测试输入数据、执行条件以及预期结果的集合,以便测试某个程序是否满足某个设定的需求。测试用例的设计需要满足以下原则:完整性、准确性、连贯性、可判定性、可操作性,通过测试用例进行测试的步骤为测试用例自动生成、测试用例执行和结果分析[9]。测试用例的自动生成包括测试输入数据的自动生成、预期结果、执行步骤、前置条件等要素,目前的测试用例自动生成技术是测试领域的一个技术难点。测试用例自动生成技术为被测嵌入式软件自动生成测试用例,自动生成测试输入数据,显著提高测试效率,实现测试自动化[12]。
基于需求的测试属于黑盒测试,无需涉及程序内部的细节,只关注软件的规格说明的系统功能,不涉及程序的内部逻辑结构和内部特效,是从输入域到输出域的一种映射,通常用于集成测试和系统测试。基于规格说明的测试从系统或模块的需求出发来产生测试用例,从各个角度进行全面测试,包括基本需求功能、非法的输入、边界和极端情况、兼容性、用户界面友好性、时间和空间性能等,设计方法有等价类划分法、边界值分析法、因果图法、错误推测法。
20 世纪80 年代,Hall 等[13-14]提出了一种基于Z 规格语言的手工测试方法,需要专业和经验丰富的测试人员,测试效率低下;随之兰毓华等[15]结合Z 语言规格说明书添加预处理编译器对输入输出的约束条件进行预处理,将关系线性谓词转换之后求解区域边界点从而自动生成测试用例;Weyuker等[16]对形式化规格说明改进,用AND/OR表示规格说明中的条件,研究了一种基于防飞机碰撞系统需求布尔规格说明的测试用例数据自动生成的方法,但只适用于过程控制系统。
嵌入式软件的实时性特点增加了测试用例的生成的困难,相同的输入在不同的时间可能会有不同的输出结果,并且嵌入式软件是多任务并发运行的,传统的软件开发设计并不适应此模式,因此引入了实时多任务(Design and Analysis of Real-Time Systems,DARTS)设计方法,结合规格说明的测试方法提出了一种基于DARTS 的实时嵌入式软件的测试用例生成模型[17-18]。过程如图4 所示,通过需求说明得到数据流图,然后根据DARTS设计方法确定任务的规则对需求进行多任务划分得到任务关系图,使用Z语言对每个测试任务的需求进行形式化规格说明,产生每个任务的测试用例集,最终根据任务之间的关系对测试用例集进行优化,减少冗余。
图4 基于DART设计的嵌入式软件测试用例生成模型Fig.4 Embedded software test case generation model based on DART design
随着20 世纪90 年代人工智能的飞跃发展,研究倾向于将人工智能技术与自动化测试技术相结合。处于动态演化中的软件会积累大量冗余的测试用例,在执行回归测试时可以复用测试用例,因此测试用例的生成问题转化为测试用例路径搜索的问题,大部分智能优化搜索算法可以应用于嵌入式软件测试用例生成,常见的基于搜索的优化算法例如遗传算法、蚁群算法、粒子群算法、随机算法和组合测试算法[19]。基于人工智能算法的测试用例自动生成中,选择合适的元启发式智能算法能够大幅提高测试效率,在迭代过程中获取反馈信息作用于生成模块,使得测试用例的生成更加智能化,降低了时间和空间复杂度,是一个动态模型的过程。
最常用的是将遗传算法应用在航空机载软件测试用例生成中。遗传算法模仿的是自然界中生物遗传的一个特性,将待测用例作为染色体编码,优胜劣汰产生最优解序列。1996年Jones[20]通过实验证明了遗传算法在测试用例自动生成方面的有效性,所需要的测试用例数量明显比随机算法少。遗传算法能够较好地在测试用例种群中产生大量次优解并且可以经过进化后成为最优解,但是迭代次数增加会降低解的多样性,速度变慢而影响了算法的性能。冯廷智[21]基于遗传算法的测试用例优先级排序对航空机载软件进行测试,通过将飞机机载环控系统综合控制器软件货舱供气旁路调节阀控制率计算功能的UML 活动图作为输入,统一转化为控制流图,进行编码后经过选择、交叉、变异搜索适应度最高的个体模块进行优先测试,证明了该方法可被用于机载软件测试用例的生成。
2.3 小结
机载软件测试特殊的操作运行平台以及严格的测试标准,嵌入式软件的测试用例更是需要专业的测试人员针对性地专门设计,测试用例设计的水平对测试效率及测试结果影响重大。测试用例自动生成包括测试输入数据的自动生成、预期结果、执行步骤、前置条件等要素。
随着时间推移过程中机载软件项目功能的动态演化积累了庞大的测试文档。大多数测试数据以文档等非结构化数据的形式存在,航空设备进行回归测试或者一些类似的需求测试时,测试人员又要花费大量额外的精力来搜索和查阅原始文档,甚至重复设计了测试用例,增加了测试用例集的管理和维护成本,极大影响了测试工作的效率和质量。
目前测试用例自动生成技术是测试领域的一个技术难点,特别是根据软件各种需求生成测试用例。大部分技术是测试输入数据的自动生成,整个测试用例的生成主要还是依靠人工编写,相关自动化技术和工具仅为辅助作用。
因此基于智能算法的测试用例自动生成方法应运而生,将此问题转化成了基于搜索的问题,通过从已有的测试用例中找出最符合当前需求的测试用例序列,测试用例复用技术在机载软件测试工具中应用已经成为目前研究的热点,再结合智能优化算法解决当搜索空间的状态爆炸式增长时搜索进程如何快速收敛的问题。
未来研究方向可着重通过人工智能技术,对机载嵌入式软件需求文档进行智能分析,将非结构化数据转化成结构化数据,该领域需要在积累大量的经验下才能逐渐完善,目前该领域仍在不断探索中,还没有完全成熟的方案。
3 基于安全性分析的测试
DO-178C 中基于安全性分析的测试过程对应于软件开发过程中的软件设计过程。根据软件失效带来的危害等级以及不同安全需求,航空电子分为A、B、C、D、E 五个等级,DO-178C 只涉及A、B、C、D 四个等级的适航要求。对于A 级软件的定义为这类软件的异常状态将会导致系统功能的失效并给飞机带来灾难性的失效状态。
软件的安全性,是指软件系统经过运行之后不存在引起系统危害行为的状况出现[22],基于安全性的机载软件测试技术以软件需求模型和安全性分析为基础,主要分为以下5个方面:危害分析[23]、软件安全需求的提取与分析[24]、软件安全性设计[25]、软件安全验证和确认[26]、软件安全认证及标准[27]。安全性测试旨在快速降低由软件故障导致的系统故障风险,并确保风险被消除或控制在可接受的风险水平,它主要包括安全性测试计划、安全性测试设计、安全性测试执行及安全性测试评估四个阶段[28]。
机载软件安全分析的框架可以分为三个部分:机载软件安全需求的获取和规范;面向安全标准的软件开发过程以及机载软件安全要求的验证[29]。徐丙凤等[30]使用系统建模语言SysML建立具有安全特征的系统静态结构模型,并将其转化为块依赖图进行精确地形式化描述,验证面向适航认证的模型驱动机载软件构件的安全性。
由于需求可追踪是安全领域标准的基本要求,也是安全性分析与保障的重要前提,王飞等[31]提出了一种基于谓词逻辑的需求追踪方法,通过两种广泛使用的标准语言SysML 和嵌入式系统体系结构分析与设计语言AADL[32]分别对系统需求与设计进行建模,基于语义模型得出追踪关系的自动推导和检验规则,用以建立精确、完整的需求追踪关系,以建立准确、完整的需求跟踪关系,有效支持嵌入式系统的安全分析和系统维护与演化;石娇洁等[33]提出了一种基于模型驱动架构的SysML/MARTE状态机系统安全分析与验证方法;曹德建等[34-35]提出了将故障树分析扩展到SysML活动图模型的方法和故障扩展SysML 活动图的概念,统一了系统的安全需求分析模型和行为模型。
在复杂的系统中通常会用到表1所示的安全性方法[36]。
表1 安全性分析方法总结Table 1 Summary of safety analysis methods
3.1 功能危险分析(FHA)
功能危险分析(Functional Hazard Analysis,FHA)是一种安全分析方法,系统地、全面地检查产品的各种功能,识别各种功能故障状态,并根据其严重程度进行分类,用来确立系统安全性设计目标,帮助决定设计方案的可接受性,发现潜在的问题和所需的设计更改,确定所需的进一步分析的要求及范围。在软件系统设计早期阶段中FHA 提供了危险鉴别方法,目的在于减少由更改或改装而带来的昂贵费用,此方法不需要考虑系统的具体模型架构,从功能角度分析不同形式的系统设备软件。
陆中等[37]分析了在民用飞机适航符合性验证中的应用的各种安全性分析方法以及输入输出信息,主要考虑的因素包括所有工作状态和模式下可能的功能;所有功能失效模式、危险组成部分,如失控、意外工作或不受指令地工作等;具有冗余或者被冗余影响的系统;每一个系统的工作状态,包括在不正常状态下的意外工作;所有功能和实际系统的相互关系;外部因素条件以及操作和维修中的人为差错的人为因素[38]。
3.2 故障模式及影响分析(FMEA)
故障模式及影响分析(Failure Mode and Effects Analysis,FMEA)是指在产品设计过程中,通过分析各组成单元的潜在失效模式及其对产品功能的影响,从而提高产品可靠性的设计方法[39]。FMEA是一种系统的、自下而上的方法,用于识别系统、单元和功能的故障模式,并确定它们对上层的影响,可以在系统的任何级别上执行(如零部件)。
通过FMEA 可以确保考虑周全所有零部件的各种故障模式和影响,找出对系统故障影响较大的部件和故障模式,分析它们的影响程度,并提出各种危险的预防措施。通常用来分析单故障的故障影响,由于FMEA分析需考虑产品结构组成等因素,因此只能在系统的详细设计阶段进行。
3.3 故障树分析(FTA)
故障树分析(Fault Tree Analysis,FTA)关注的是导致系统失效的故障行为,以系统的一个具体故障为分析对象,分析可能导致故障的各种因素,确定发生故障的各种可能原因,并通过发现系统的设计错误和安全隐患,用于指导逻辑门等符号直观地描述故障与故障成因之间的逻辑关系,从而提前软件设计和后期维护。
故障树分析主要包括定性分析和定量分析。定性分析是找出导致顶层事件的所有可能的失效模式,分析各类失效的风险,定位安全薄弱环节,安排预防措施避免失效。定量分析确定了每个基本事件的发生概率,并计算出顶层事件的发生概率,作为系统安全评估的评分标准之一,为系统安全优化提供科学依据[40]。
3.4 共因故障分析(CCA)
共因故障是由于空间环境、设计以及人的因素所造成的失误,其中引发故障不是独立的事件,可能由于某种单一的共同原因,造成多个同时故障,复杂系统通常采用余度设计来提高其可靠性,共因故障的存在使得冗余系统的可靠性降低,共因故障分析(Common Cause Analysis,CCA)由此产生。CCA 包括特殊风险分析(Particular Risks Analysis,PRA)、共模故障分析(Common Mode Analysis,CMA)和区域安全性分析(Zonal Safety Analysis,ZSA)三种分析方法。
PRA主要分析系统外事件或因素对系统的影响,如泄漏物、飞禽撞击、雷电、高强度辐射等,是造成共因失效的重要原因。总体分析过程是为待研究的具体风险逐一建立合适的失效模式,确定受影响的区域,并审查具体风险的后果[41]。
CMA 是一种用于复杂系统可靠性、安全性和风险性评价的方法,是故障模式与影响分析和故障树分析的补充,分析共因事件对余度设计影响的重要方法,主要分析故障树分析中“与门”输入事件的独立性,CMA 分析内容涵盖了设计、制造和维修失误以及相同软硬件故障等方面。
ZSA 主要分析设备安装和故障对相邻系统或结构的影响,避免相邻系统之间的相互干扰,确保系统满足安全要求。ZSA只能在详细设计阶段进行,是抑制共因失效产生的重要措施。主要判断系统各个区域的物理功能是否相关,明确系统的组成和结构[42]。
3.5 小结
目前常规的安全性分析测试流程,大多是以机载软件适航标准体系参照的。虽然国内的机载软件安全性测试研究工作有一定发展,但是发展相对滞后,安全性测试框架还比较零散,尚未形成系统的安全性测试框架体系,指导单类型的测试框架居多,但指导流程性质的安全性测试活动的框架较少。
很多安全性问题需要在系统环境中才可能会被挖掘出来,仿真测试环境并不能彻底暴露出所有隐藏风险,而且安全性测试框架不具有普遍性,自动化测试分析技术水平远远达不到测试标准,对于大型复杂的机载软件的安全性分析难度较大且繁琐。将来可依据当前测试框架开发出具有普适性的安全性自动化测试分析工具,使其能够与测试用例生成模块相关联,提高测试效率及覆盖率。
4 基于模型的测试
DO-178C 中基于模型的测试过程对应于软件开发过程中的软件编码和集成过程。模型是软件生命周期数据的一种抽象描述方式,用来更好地支持软件开发过程和软件验证过程。不同的软件系统采用合适的方法自动生成测试用例,随着软件面向对象的开发思想封装、继承、多态性的出现,面向对象的测试用例也随之而来[43]。面向对象的测试用例的生成方法根据程序的内部结构和形式化规范分为基于外部行为和内部结构,基于外部行为就是根据类与类之间的外部接口,而基于内部结构则是以模型为基础,描述软件的内部作为。根据软件结构模型和行为模型就可以生成测试用例,基于各种测试模型的测试用例有效提高了测试的效率,典型的模型有:有限状态机FSM(Finite State Machine)、统一建模语言UML(United Modeling Language)模型、系统建模语言SysML(System Modeling Language)模型和Markov(马尔科夫)链模型。如图5 所示为测试模型建模过程。
图5 基于模型的测试用例设计过程Fig.5 Design process of test case
4.1 FSM测试模型
基于有限状态机FSM 的测试模型[44]是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型,当前状态影响可能的输入数据,将测试输入数据表示为一个序列的输入,即利用图的遍历算法自动产生,是基于一个状态转换的前提下生成测试用例模型。但是目前机载嵌入式软件十分复杂,所以需要表示的状态机也很复杂,工作量比较大,而且生成的测试用例的数目也会达到一个上限值。
4.2 UML测试模型
有限统一建模语言UML是面向对象软件的一个通用的标准可视化建模语言,逐渐在机载软件开发过程中应用,侯晨光[45]针对机载设备软硬件一体化测试剖面按照航空电子系统执行任务剖面分层设计,分为任务层、状态层和用例层,不同层次采用不同的UML 视图可视化和编制各种开发文档中各种复杂的说明信息,将系统架构从不同角度建模从而形成丰富的视图。UML包括静态图和动态图两大类图,根据不同的测试目的从而选择不同的UML 图形,然而功能性测试关注的大部分是系统模块之间进行交互的状态信息。
Martin 等[46]提出在实时嵌入式系统开发中完全适合使用UML 模型,其中状态图作为嵌入式软件测试中常用的模型图,是有限状态机的扩展,通过采用有效的动态建模描述状态图的状态转移过程生成测试用例的序列。因此殷永峰等[47]提出了一种基于UML的嵌入式软件测试用例生成方法,选取典型的航空电子设备惯导系统软件静态和动态建模并将生成的测试用例采用扩展标记语言格式存储。然而UML在嵌入式实时系统上缺少一致性原则,操作性差,建模容易不完整导致安全缺陷问题。
4.3 SysML测试模型
系统建模语言SysML 是目前最新的标准建模语言,是对系统工程领域中的统一建模语言UML 的完善和扩展,提供了活动图形表示,支持指定、分析、设计和验证复杂的系统中的硬件、软件、信息、人员、程序和设施。
SysML 活动图扩展了传统的UML 活动图,2015 年黄传林[48]在面对嵌入式实时系统中安全性验证中提出了基于扩展的MARTE(Modeling and Analysis of Realtime and Embedded Systems)时钟语义信息到SysML活动图的方法,通过结合嵌入式实时紧急呼叫系统验证了可行性,弥补了UML 系统建模的不足。目前关于使用SysML 活动图生成测试用例序列的研究较少,对测试用例序列的优先级排序方面也较少研究,需要克服SysML 半形式化语言的缺陷,并且不能自行分析和验证。曹伟芳[49]使用SysML活动图对IMA系统中的飞机导航系统和飞机着陆过程的活动图进行建模验证,自动化生成集成测试序列并提出最佳快速覆盖方法对优先级排序进行判定。
4.4 Markov链测试模型
马尔科夫Markov 链模型基于统计学理论,实际上是有限状态机的一种特殊情况,此模型通过包含的概率信息得到状态之间的迁移概率来自动地产生测试用例序列,常用于衡量软件可靠性测试,通过实例证明了将Markov链模型运用在嵌入式可靠性测试中可以有效地评估可靠性,Markov 过程中任何一个事件的发生都只与当前状态有关,一个测试用例对应一个状态,从而形成一个基于马尔科夫链模型的完整测试用例集[50]。
在基于动态故障树模型的测试用例设计中[51]分析动态故障树时利用Markov对树进行划分从而获取最小割集,即最终达到测试用例生成的目的,然而考虑到嵌入式系统的复杂性,建立动态故障树存在一定难度。因此嵌入式软件的实际使用状况可以使用带标记的Markov链进行描述,测试用例和测试数据的等价类信息可以通过任务剖面模型来获取,从而自动生成测试用例,大大减少测试人员的工作量,提高测试效率[52]。
4.5 小结
基于模型的测试是根据系统的设计模型的逻辑关系生成软件测试用例,尽可能提高软件测试的充分性,将测试工作提前到开发过程早期。
通过模型可产生大量的测试用例,提高软件的易测性。因此一套高效的航空机载软件测试模型,需要根据航空机载软件任务书或需求规格说明文件提出的测试需求,建立需求追踪关系模型图,最后进行测试用例的设计,最终获得好的测试结果和全面测试覆盖率。
航空机载软件的测试模型需要不断地融合构建其他更多的通用测试模型,推广到各种机载嵌入式软件系统中,不断优化使其具有通用性和可扩展性。
5 软件验证的测试
DO-178C 中软件验证的测试过程对应于软件综合过程中的软件验证过程,此过程贯穿软件生命周期全过程。根据对软件验证过程输出结果的验证中,列出了如下9个目标。
(1)测试规程正确。
(2)测试结果正确,并且解释差异性。
(3)实现对高级需求的测试覆盖。
(4)完成对低级需求的测试覆盖。
(5)完成对软件结构(MC/DC)的测试覆盖。
(6)完成对软件结构(判定覆盖)的测试覆盖。
(7)完成对软件结构(语句覆盖)的测试覆盖。
(8)完成对软件结构(数据耦合DC和控制耦合CC)的测试覆盖。
(9)验证无法追溯到源代码的附加代码。
在机载软件开发中,验证活动是贯穿软件生命周期的整体过程,而软件测试是验证的关键,划分为静态审查和分析,需求覆盖测试,结构覆盖测试以及数据耦合和控制耦合测试,以满足不同的软件级别要求。
5.1 静态审查和分析
静态审查和分析是指针对需求说明、设计文件等文档和源程序,不运行程序代码的情况下,通过形式化验证技术如模型检测、符号执行、定理证明、约束求解等扫描代码达到程序分析的目的,验证代码是否满足规范要求。DO-333是对机载软件标准DO-178C中关于形式化方法的补充,为机载软件开发过程中形式化方法的使用提供指导。通过形式化方法可以对机载安全等级依赖的合法性[53]进行分析。陈光颖等[54]基于DO-333使用模型检验对飞控系统中的襟缝翼控制单元进行验证和分析,判断其是否满足DO-178C 的相关要求。面向适航标准采用形式化方法对机载襟缝翼控制单元进行安全性分析。黄怿豪等[55]提出了一种面向航空领域的机载控制软件需求建模形式化工程方法ACSDL-MV,包含了演化形式化规约构建和需求规约确认。
5.1.1 测试规程测试
针对DO-178C 的第一个目标(测试规程正确),一般采用同行评审的方式对测试规程进行验证,同行评审的对象是软件需求文档、模型和数据。测试用例的评审和测试规程的评审是同步进行的。
对测试用例的评审主要是检查测试用例是否正确并且充分测试了需求,每个测试用例都应该包含对需求的追踪、测试目标、测试输入、测试条件、期望结果和通过判定准则等信息。
对测试规程的评审主要检查以下3个方面。
(1)测试配置信息是否齐全,包括测试规程版本,测试配置文件版本、所需环境配置以及对应版本等必需信息。
(2)测试规程的测试步骤是否与测试用例相符,正确实现了测试用例要求。如果是可执行的测试规程,则提交评审时最好有实际运行结果,以便检查测试规程本身不包含语法错误,可以正确运行。
(3)测试规程的设计和实现是否和软件验证计划SVP相符。
测试规程评审的步骤和其他需求评审、代码评审类似,也需要有检查单、评审计划和评审记录等。测试规程评审人员包括除了作者以外的测试人员,还应邀请软件开发人员和质量保证人员参加。
5.1.2 测试结果测试
针对DO-178C 的第二个目标(测试结果正确),一般采用同行评审的方式对测试结果进行验证。测试规程的执行结果放入测试结果文件中,评审主要审查以下3个方面。
(1)测试结果文件内容是否完整,包括被测软件、硬件和设备等信息;测试执行人、测试时间信息。
(2)测试规程是否正确执行,每个测试用例都被执行并且表明是否通过。
(3)如果测试结果表明和期望不符,则要说明不符的原因。如果是代码或需求问题,则要有说明,并指向相应的问题报告。
王泉等[56]根据嵌入式平台软件的特点提出一种基于Polyspace 的静态分析和测试方法,结合Polyspace 测试工具和人工进行静态分析,同时借助SVN 配置管理工具进行同行评审,有效提高了软件质量。
5.2 需求覆盖测试
针对DO-178C的第三、第四个目标实现了软件高、低层需求的测试覆盖,通常采用验证方法中的分析方法实现,对需求测试的覆盖度进行进一步的验证。
在测试规程评审阶段,就包含了对测试用例是否完整覆盖测试需求的审查,在这一阶段确保测试用例所追踪的需求被完整、充分地进行了测试。在所有测试用例开发结束后,还应对所有需求进行一次整体的检查,确保没有遗漏。在这个过程中,要生成需求和测试用例之间的追踪表,作为分析的结论依据。
5.3 结构覆盖测试
针对DO-178C 的第五、第六和第七个目标实现了软件结构覆盖测试。结构覆盖是针对软件代码的覆盖分析,包括源代码、目标码和可执行代码,属于白盒测试,关注程序内部的代码,主要是根据程序内部逻辑结构来设计测试用例,通常用于单元测试。DO-178C关于不同等级的软件有不同的软件结构覆盖要求,将机载软件分为A、B、C、D、E 五个级别,并从软件规划、软件开发、软件验证、软件配置管理、软件质量保证和软件适航认证六个方面对不同级别机载软件的开发过程提出了不同程度的要求[57]。在DO-178C 标准对于A 级软件的定义为这类软件的异常状态将会导致系统功能的失效并给飞机带来灾难性的失效状态。基于需求的测试已经完成,并且进入配置库以后,才可以进行结构覆盖分析。
测试覆盖是指测试用例相对某个特定的覆盖准则而言的覆盖情况,是用来度量测试完整性的手段。覆盖率是指至少被覆盖一次的测试对象数量占测试对象总数的比例。覆盖分析主要评估软件测试用例及其测试活动的完备性,间接地可用来评估软件需求的完整性,从而保证机载软件测试活动达到相应等级的适航要求。
目前结构化测试有三种测试用例生成的方法:随机测试用例生成方法、面向目标的测试用例生成方法和面向路径的测试用例生成方法[58]。
随机测试用例的生成实现简单,在输入域内随机选取测试用例,即利用随机算法生成的测试数据作为输入执行被测软件[59],这种方法简单易实现但是缺乏针对性,难以覆盖到整个软件的测试范围。面向目标的测试用例生成方法依据的是程序的控制流信息,测试用例生成时依据分支函数的极小化原则[60],这种方法无关于路径的选择,可以达到语句覆盖、分支覆盖级别,但在结构测试覆盖准则中覆盖强度依旧是较低的,只有当程序中每一条路径都被测试了,才属于全面的测试。
大部分软件测试的研究集中在面向路径的测试,可分为基于符号执行和基于实际程序执行两类[61]。单元测试中的各种控制流测试过程中,语句覆盖SC、分支覆盖DC、条件覆盖CC、条件/判定覆盖CDC、路径覆盖PC、修正条件/判定覆盖MC/DC等问题可视为面向路径的测试用例生成问题。在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例的方法。这种方法可以很方便地得出所需测试用例的最小值,有效地减轻测试人员的劳动强度,提高测试的效率和质量,节省软件开发的成本。
在航空类软件的测试中,满足的覆盖率标准为最高覆盖强度的修正条件/判定覆盖(Modified Condition/Decision Coverage,MC/DC),百分百确保解决掉所有将导致航空器灾难性故障的软件问题[62],这需要设计足够多的测试用例,保证判定中每个条件的所有可能结果至少出现一次,每个判定本身的所有可能结果也至少出现一次;每个程序模块的入口和出口至少要被调用一次,并且每个条件都显示能独立影响判定结果[63]。然而,无论哪种结构化测试方法,即使其覆盖率达到100%,也不能保证暴露所有隐藏的程序缺陷。
如图6所示,嵌入式软件的测试用例需全面覆盖宿主机、目标机,首先通过插桩分析器对源代码进行插桩,以便后续记录测试用例覆盖的路径信息;然后对插桩后的程序源代码编译生成可执行程序后,根据MC/DC 覆盖补充得到的测试用例运行程序后便可采集分析覆盖信息;最后得到相应的覆盖率信息并生成测试报告。在嵌入式软件的测试过程中,由于测试所需要的信息在目标机上才会产生,所以必须通过一定的物理逻辑连接传输到宿主机上[64-65]。
图6 嵌入式软件覆盖测试过程Fig.6 Coverage test process of embedded software
5.4 数据耦合和控制耦合覆盖测试
针对DO-178C的第八个目标实现DO-178C对A级软件有数据耦合和控制耦合分析的要求,同时DO-178C对控制耦合和数据耦合进行了定义。
数据耦合是指一个软件组件对不完全受制于自己的数据的依赖,一个模块访问另一个模块时通过数据参数(不是控制参数、公共数据结构或外部变量)交换输入输出信息。控制耦合是一个软件组件影响另一个软件部件运行的方式或程度,一个模块通过传送开关、标志和名字等信息控制选择另一个模块的功能。
耦合的实质是单一接口上选择多功能模块中的某项功能。模块间的耦合越紧密,系统越复杂,设计、编码、测试和维护的成本越高,因此对安全级别高的软件进行数据耦合和控制耦合的分析,使模块间的耦合最小化,相互依赖性最小化,保证模块间的独立性,模块间联系简单,发生在某一处的错误传播到整个系统的可能性越小。耦合关系是衡量软件架构可靠性的重要指标,对于高安全性和高可靠性的机载软件而言,数据耦合和控制耦合分析更尤为重要。
数据耦合和控制耦合采用评审、分析、测试三种验证方法结合的方式,在开发过程中通过评审和分析方法确保软件架构的一致性,验证源代码与软件架构的符合性,通过测试方法说明数据耦合和控制耦合关系得到正确运行,分析确保所有的数据耦合和控制耦合关系得到覆盖。基于DO-178C的数据耦合和控制耦合分析的具体步骤如下:
(1)根据软件架构,识别软件部件之间的耦合关系。
(2)对每个耦合关系,分析有哪些方面的耦合内容/覆盖准则。
(3)对每个耦合内容/覆盖准则,列出应该覆盖到的覆盖点。
(4)通过分析、插桩、运行等手段,识别有哪些覆盖点没有覆盖。
(5)对没有覆盖到的覆盖点,分析问题,修改代码或给出解释。
(6)回归,直到所有覆盖点全部被覆盖(或解释)。
(7)形成数据耦合/控制耦合覆盖的分析报告。
上海爱韦讯信息技术股份有限公司研发了耦合覆盖分析工具——SA-Covalyzer软件耦合覆盖分析工具,实现软件架构的测试覆盖分析,提高测试充分性,提供了一套完善的解决方案,支持软件部件的定义,自动识别部件间的耦合关系,推荐适用的覆盖准则,针对覆盖点进行低膨胀率的插桩,在测试过程中收集、累积和统计覆盖情况,对未覆盖到的情形进行辅助分析,并自动生成覆盖分析报告。
5.5 小结
静态审查和分析虽然不执行源代码,只是进行静态扫描,执行速度快效率高,但是存在一定的误报,不能仅仅依靠工具或人工,只有结合静态分析工具和人工分析才能真正有效提升软件质量。
DO-178C是基于过程控制对机载软件进行管理,对如何进行覆盖分析只进行了简单的指南性的描述,对覆盖分析的过程和实现并未提及。国内进行基于DO-178C 的覆盖分析的研究和实践才刚起步,国内机载软件的软件验证活动,测试覆盖都是一个较难解决的问题。工程经验证明,覆盖分析难度大,成本高,完成基于需求的测试后进行覆盖分析可以有效地节约软件验证成本。
DO-178C中所有验证活动都是基于需求的,基于代码结构的测试难以满足适航局方的要求。对于耦合覆盖分析,DO-178C没有给出明确的覆盖准则甚至没有指导思想,只能依据项目需求、架构以及耦合覆盖分析的适航审定标准才能确定覆盖准则,普遍认为数据耦合和控制耦合的覆盖分析测试是个难题,在国内外的适航项目中属于普遍的薄弱环节。
现有大部分工具通常只能实现粗略的耦合分析,如函数调用(控制耦合)、全局变量的读写异常(数据耦合)等。而实际工程中,部件间的耦合涵盖了更细致、更复杂的内容,如函数调用时的参数类型一致性、数据的先读后写和先写后读、数据的轮流写入等,针对这一方面需要研发更多追求细节的耦合覆盖分析工具。
6 总结
本文根据美国RTCA 制定的DO-178C 标准中的软件生命周期从基于需求、基于模型、基于安全性分析以及软件验证的测试研究机载软件的测试验证方法,并进行了小结。以下是研究过程中发现的一些问题。
(1)机载嵌入式软件测试中测试用例自动方法是通过在宿主机上运行测试管理系统和在目标机上运行测试调度软件的方式,来共同完成对机载软件的测试,测试环境支持测试用例的加载,最终记录和分析测试结果。测试环境相对于一般商用软件较为特殊,交叉开发软件的测试较为困难。
(2)机载航电系统经历数字式、分布式、综合式三大阶段,对于不同的阶段有不同的测试方法,目前大多数都是综合航电系统IMA。大多数航电系统中软件测试验证仍然停留在传统架构下,测试过程中IMA 系统硬件环境资源有限,缺乏目标机测试环境,即使存在目标机环境也会被占用而其他人员无法使用,导致资源的浪费,测试效率低下。
(3)从安全性分析方面对机载软件测试有助于发现软件的隐藏风险,采用传统的安全性分析方法目前更多的是关注机载软件的系统层面,仅仅分析了故障危害过程,缺乏针对机载软件的特征而采用合适的故障危害分析方法,对于其他阶段无法简单套用此分析方法。
(4)国际标准过于抽象化不易理解,与国内机载系统的结合不太匹配,国内机载软件测试的标准体系的制定起步较晚并且缺乏完善性,2008 年GJB5000A—2008《军用软件研制能力成熟度模型》才被提出,此标准适用范围过于广泛以至于对软件验证的细节方面不明确详细,并且更注重于软件开发过程逐步发展完善,此标准更适用于机载软件开发过程而不适合软件验证审定。
在实际的测试工作中,无论采用什么样的测试方法,都应该尽早地进行测试,越早发现问题,软件开发的成本越低。研究面向适航标准的机载软件测试验证方法过程中,总结了一些发展研究建议。
(1)在现代航空领域中,现代飞行器系统开始采用了综合模块化航电系统(Integrated Modular Avionics,IMA)架构,此构架系统表现出多任务、综合化、模块化、统一网络、高度集成的特点。随着IMA 软件在系统中占比逐渐增加,分布式测试平台可为IMA 软件测试提供有力保障,目前平台仅支持ARINC653 标准操作系统,可就提高这一平台的通用性进行更进一步的研究。
(2)我国适航标准在未来发展上,一方面可以借鉴国外优秀的主流适航标准,另一方面在时机成熟情况下,可以从自身航空产品及航空器的特点进行研究和创新,研制出具有中国特色的适航标准体系。
(3)目前国内针对于机载嵌入式软件测试的研究工作还处于初期阶段,测试过程缺乏标准化管理体系,未来需要研究嵌入式软件测试过程管理体系标准化,并且将自动化测试越来越多的应用到嵌入式软件测试中。