2. 单元测试在航空软件生命周期中的位置

在航空机载软件研制中,单元测试并不是一个孤立的“编码后补做”的环节,而是嵌入在需求、设计、编码、验证这条纵向链条中的关键验证节点。要理解它的位置,最有效的方式是抓住两条线索:一条是从需求到代码的追溯链,另一条是单元测试与低层需求的对应关系。前者回答“这个单元为什么存在、它实现了哪条需求”,后者回答“我们用什么依据来验证它、验证到什么程度算通过”。

航空软件通常按 DO-178C 的思路把需求分为高层需求(HLR)和低层需求(LLR)。高层需求描述系统/软件层面的功能与性能,例如“大气数据计算机应在 0.5 s 内输出修正后的气压高度”;低层需求则把高层需求分解到可实现的软件单元粒度,例如“高度解算单元应使用气压高度公式 H = 44330·(1−(P/P₀)^0.1903) 计算,输入范围 100~1100 hPa,输出分辨率 1 ft”。单元测试的直接验证对象就是低层需求,而不是笼统的高层需求。因此,追溯链的正确形态是:HLR → LLR → 源代码单元 → 单元测试用例 → 测试结果,每一环都必须双向可追。

下面这张图给出了单元测试在生命周期中的位置及其与需求追溯、就绪评审的关系。图中左侧是需求与设计的下行分解,中间是单元测试的输入与执行,右侧是评审准入与结果回写。

高层需求 HLR 功能/性能/接口约束 低层需求 LLR 算法/范围/精度/异常 源代码单元 函数/模块/类 分解 实现 单元测试 测试用例(正常/边界/异常) 桩/驱动 + 覆盖率采集 语句/分支/MC-DC 判定 被测 测试就绪评审 TRR 准入 • LLR 已评审基线,无 TBD/TBR • 代码已通过静态分析与编译 • 用例与 LLR 双向追溯已建立 • 测试环境/桩/预期结果已就绪 测试结果与追溯回写 • 用例通过/失败记录 • 覆盖率达标(如语句100%、分支100%) • 缺陷关联到 LLR 与代码行 准入 执行 双向追溯链:需求 → 设计 → 代码 → 测试 HLR 编号 LLR 编号 代码单元/行号 测试用例 ID 结果

单元测试与低层需求的对应关系

单元测试的“验证依据”必须来自低层需求,而不是测试人员凭经验临时构造。对应关系通常体现在三个维度上:功能对应、边界对应和异常对应。以“高度解算单元”为例,低层需求可能写成:输入气压 P 范围 100~1100 hPa,输出高度 H 范围 −1000~50000 ft,当 P 超出范围时输出无效标志并保持上一次有效值。那么单元测试至少应覆盖:

  • 正常点:P = 1013.25 hPa,期望 H ≈ 0 ft(标准大气海平面);
  • 边界点:P = 100 hPa 与 P = 1100 hPa,检查输出是否在允许范围内且不溢出;
  • 异常点:P = 90 hPa 与 P = 1200 hPa,检查无效标志置位、输出保持逻辑是否正确;
  • 精度点:在 P = 500 hPa 处,按公式计算期望值并与实际输出比较,容差按 LLR 规定(例如 ±2 ft)。

这些用例的编号、输入、预期输出和实际结果,都要能反向追溯到具体的 LLR 条目。如果一条 LLR 找不到任何用例,说明覆盖有缺口;如果一个用例找不到对应 LLR,说明它可能是冗余的或需求本身缺失。这种双向检查是单元测试评审中最常被追问的内容。

测试就绪评审的准入条件

测试就绪评审(Test Readiness Review,TRR)是单元测试正式执行前的“放行关口”。它的核心不是走形式,而是确认“现在开始跑测试,结果是否可信”。在航空软件项目中,TRR 的准入条件通常包括以下几类,缺一不可:

类别 准入条件 判断依据
需求基线 被测单元对应的 LLR 已通过评审并纳入基线,无 TBD/TBR 遗留 需求评审记录、基线清单
代码状态 代码已完成并通过编译、静态分析,无未解决的严重告警 编译日志、静态分析报告
追溯关系 LLR ↔ 代码单元 ↔ 测试用例三者双向追溯已建立并检查通过 追溯矩阵、覆盖分析表
测试资产 测试用例、预期结果、桩/驱动、测试数据均已评审并冻结 用例评审记录、测试环境说明
环境与工具 目标编译器/仿真器、覆盖率工具、版本控制状态已确认可用 环境检查单、工具鉴定记录

需要特别注意的是,TRR 不是“测试做完后的总结会”,而是“测试开始前的准入检查”。如果 LLR 还在频繁变更,或者代码还在合入新功能,那么此时跑出的覆盖率再高也不具备验证意义,因为被测对象本身不稳定。工程上常见的做法是:在 TRR 上逐条核对上述条件,任何一条不满足就挂起,直到关闭后再重新评审。

实践提示:追溯矩阵不要等到 TRR 前才补。建议在编写 LLR 时就分配唯一编号,在代码提交时在注释中标注对应的 LLR 编号,在编写用例时直接引用该编号。这样追溯关系是“长出来的”,而不是“补出来的”,TRR 的检查成本会大幅降低。

把这三件事放在一起看,单元测试在生命周期中的位置就清晰了:它向下承接代码实现,向上验证低层需求,向左依赖需求基线与追溯关系,向右输出可判读的测试结果与覆盖率证据。TRR 则是这个位置上的“闸门”,确保测试是在受控、可追溯、可复现的条件下开始的。只有这个位置站稳了,后续的集成测试和系统测试才有可信的输入。