1. 航空嵌入式软件测试概述

航空嵌入式软件与通用商业软件最根本的差别,不在于代码规模,而在于它一旦失效,后果往往直接指向飞行安全。它通常运行在资源受限的处理器上,与传感器、作动器、总线紧密耦合,具有强实时性、高可靠性和长生命周期特征。例如一台全权限数字发动机控制器(FADEC)中的软件,需要在毫秒级周期内完成采样、控制律计算与执行机构输出,任何一次超时或数值异常都可能被放大为推力失控。因此,航空嵌入式软件的测试不是"验证功能是否实现"这么简单,而是要回答一个更严格的问题:在可预见的运行条件下,软件能否持续、确定、可追溯地满足安全要求。

航空嵌入式软件的典型特点

理解测试约束之前,先要看清被测对象的性质。航空嵌入式软件通常具备以下特征:

  • 强实时与周期性:控制律、余度管理、健康监控多按固定周期调度,周期抖动和截止期错失本身就是缺陷。
  • 资源受限:CPU 主频、内存、堆栈、总线带宽都经过严格预算,动态内存分配常被禁止或严格限制。
  • 与硬件强耦合:软件行为依赖 ADC 采样、离散量、ARINC 429/CAN 总线、看门狗等硬件接口,脱离目标环境难以完整验证。
  • 高安全等级与冗余:常见双余度、三余度通道,配合比较监控或表决逻辑,软件需在故障注入下仍保持安全状态。
  • 长生命周期:一款机载软件可能服役二三十年,需求、代码、测试用例、验证证据都必须可追溯、可复现。

这些特点直接决定了测试策略:不能只做输入输出等价性检查,还要覆盖时序、资源、故障与边界行为。

适航要求对测试的约束

民用航空软件研制受 DO-178C《机载系统和设备合格审定中的软件考虑》约束。它并不规定"必须写多少测试用例",而是要求研制过程具备目标可满足、活动可计划、数据可追溯、结果可验证的性质。对测试而言,最直接的约束体现在三方面。

第一,测试目标与软件等级绑定。软件等级由失效对飞机安全的影响决定,从 A 到 E 逐级降低。A 级软件要求满足全部目标,包括对源代码的结构覆盖;等级越低,目标数量越少。这意味着测试深度不是由团队主观决定,而是由等级推导出来的。

第二,测试必须基于需求并可追溯。每条测试用例都应关联到具体的高层需求或低层需求,形成"需求—用例—结果—覆盖"的闭环。适航审查时,审查代表会抽查这条链是否完整、是否存在无需求依据的测试或未被测试覆盖的需求。

第三,验证独立性。对于高等级软件,测试活动应由独立于开发的人员执行或评审,以降低"自己验证自己"带来的偏差。同时,测试环境、工具若参与验证,还需按 DO-330 进行工具鉴定。

常见误区:把"测试通过"等同于"满足适航要求"。适航关注的是过程证据是否充分、目标是否被满足,而不是某一次测试是否绿灯。缺少追溯关系或覆盖分析的测试结果,即使全部通过,也难以作为合格审定证据。

单元测试与集成测试在 DO-178C 中的定位

DO-178C 把软件生命周期划分为多个过程,其中验证过程包含评审、分析以及测试。测试又分为两大类:软件单元测试与软件集成测试,二者目标不同、对象不同、证据也不同。

软件单元测试针对最低层软件单元(通常是一个函数或一个模块),目标是验证单元实现与其低层需求一致,并确认单元在边界、异常和鲁棒性条件下的行为。对 A 级软件,单元测试还需满足结构覆盖目标,常见包括语句覆盖、判定覆盖、修正条件/判定覆盖(MC/DC)。例如一个限制器函数 limit(x, lo, hi),单元测试不仅要验证正常区间,还要验证 x < lo、x > hi、lo == hi 以及输入为 NaN 等异常情形,并证明每个判定的独立影响都被执行到。

软件集成测试针对已集成的软件组件或模块之间的接口与交互,目标是验证组件间接口、数据流、控制流以及资源使用符合高层需求与设计。它关注的不是单个函数内部逻辑,而是"拼起来之后是否还对"。典型内容包括:调用时序、参数传递、共享数据一致性、中断与任务间通信、初始化顺序、故障传播路径。例如飞控软件中,传感器采集模块与余度表决模块集成后,需要验证当某一路信号超范围时,表决逻辑是否正确隔离该通道并输出安全值。

可以用下面的关系图理解二者的分工与衔接:单元测试在"函数/模块"粒度上建立正确性基础,集成测试在"组件/接口"粒度上验证协作正确性,二者共同支撑后续的软件合格性测试与系统验证。

DO-178C 验证过程中的单元测试与集成测试定位 需求基线:高层需求(HLR) + 低层需求(LLR) 每条需求可追溯 · 软件等级 A~E 决定目标集合与覆盖深度 软件单元测试 对象:最低层软件单元(函数/模块) 目标:实现与 LLR 一致,边界/异常鲁棒 覆盖:语句 · 判定 · MC/DC(A级) 示例:limit(x,lo,hi) 的 NaN、lo==hi 证据:用例 · 结果 · 覆盖分析报告 关注点:单元内部逻辑正确性 软件集成测试 对象:组件/模块间的接口与交互 目标:接口、数据流、控制流符合 HLR/设计 覆盖:接口 · 调用时序 · 故障传播 示例:采集→表决→隔离超范围通道 证据:集成用例 · 接口验证 · 时序记录 关注点:组件协作与资源使用正确性 衔接 软件合格性测试 / 系统验证 在单元与集成测试证据基础上,验证软件满足高层需求 等级 A~E 决定深度

从目标到实践:测试活动如何落地

把上述定位落到工程实践,可以按以下逻辑组织。首先依据软件等级和需求确定测试目标集合,明确哪些覆盖指标必须达成。其次为每个单元建立测试用例集,用例输入应覆盖正常值、边界值、非法值和异常值,并记录预期输出与判定依据。然后按集成顺序(自底向上、自顶向下或基于功能)逐步集成,针对每个接口设计用例,验证参数范围、调用顺序、超时与错误返回。最后汇总覆盖分析结果,对未覆盖的分支或条件给出合理解释或补充用例。

以一个简化的发动机转速限制单元为例,其低层需求为:当转速 N 超过上限 N_max 时输出限制标志并请求降油。单元测试至少应包含:N < N_max(不触发)、N == N_max(边界)、N > N_max(触发)、N 为无效值(传感器故障)四类输入,并检查输出标志与降油请求是否符合预期。集成测试则进一步验证:当该单元与传感器采集、燃油控制单元集成后,超限信号能否在规定的控制周期内传递到执行机构,且不会因任务调度延迟而错过截止期。

教学提示:单元测试与集成测试不是"先做哪个"的简单顺序问题,而是两种不同粒度的验证视角。单元测试建立局部正确性,集成测试暴露接口与协作缺陷。二者证据共同构成适航审查中"验证充分性"的基础。

需要强调的是,DO-178C 对测试的要求始终围绕"目标—活动—证据"展开。测试人员不仅要会设计用例、执行测试,更要能说明每个用例对应哪条需求、覆盖了哪个目标、结果如何判定。这种可追溯、可审查的测试思维,是航空嵌入式软件测试区别于一般软件测试的核心所在。