3. 安全关键软件测试核心概念

在无人机安全关键软件测试中,测试活动并不是“把功能跑一遍”这么简单。它需要围绕一组核心概念建立判断标准:我们做的是验证还是确认?每条需求是否可追溯?测试是否足够覆盖?测试过程是否具备独立性?软件在异常输入和边界条件下是否鲁棒?一旦发生故障,系统能否进入失效安全状态,或通过容错设计继续维持安全运行?这些概念共同构成了安全关键软件测试的“度量尺”和“设计约束”。

一、验证与确认:做对与做对的事

验证(Verification)关注“我们是否正确地构建了产品”,即软件实现是否符合需求规格、设计文档、接口定义和编码规范。它通常通过需求评审、设计审查、静态分析、单元测试、接口测试和代码覆盖率分析来完成。确认(Validation)关注“我们是否构建了正确的产品”,即软件在真实任务场景中是否满足用户和适航安全目标。它更依赖系统测试、场景测试、飞行试验、故障注入和运行环境验证。

在无人机飞控软件中,验证可能表现为“高度控制律的输出是否满足设计公式”;确认则表现为“在阵风、GPS 漂移和电池电压下降同时发生时,无人机是否仍能安全返航或迫降”。两者缺一不可:只做验证,可能做出一个完全符合文档却不符合实际安全需求的产品;只做确认,则可能在后期才发现大量接口和实现缺陷,成本急剧上升。

核心区别:验证回答“是否符合规定”,确认回答“是否满足预期用途”。安全关键软件必须同时建立验证证据和确认证据,并保证两者可追溯、可审查、可复现。

二、需求追溯:从安全目标到测试用例

需求追溯是安全关键软件测试的骨架。它要求从顶层安全目标出发,逐层分解到系统需求、软件需求、设计元素、代码单元和测试用例,并建立双向链接。正向追溯用于确认“每条安全需求都有测试覆盖”;反向追溯用于确认“每个测试用例都能追溯到需求来源”,避免无效测试和遗漏测试。

在工程实践中,需求追溯通常以追溯矩阵形式维护。例如,一条“失去 GPS 信号后 2 秒内进入姿态保持模式”的安全需求,应向下追溯到控制模式切换模块、GPS 有效性判断函数、姿态控制器接口,以及对应的故障注入测试用例和飞行场景测试用例。若某条需求没有测试用例,或某个测试用例没有需求来源,追溯矩阵就会暴露缺口。

三、覆盖率:不只是代码行覆盖

覆盖率是衡量测试充分性的重要指标,但安全关键软件不能只看“代码行覆盖率”。常见覆盖层级包括语句覆盖、分支覆盖、条件覆盖、MC/DC(修正条件/判定覆盖)、接口覆盖、需求覆盖和场景覆盖。对于无人机安全关键软件,MC/DC 往往比语句覆盖更有价值,因为它能揭示复合条件中某个子条件未被独立验证的风险。

例如,一个返航判断条件为:if (gps_valid && battery_level > 20 && wind_speed < 12)。语句覆盖可能只执行到该语句一次,但 MC/DC 要求每个子条件都能独立影响判定结果。若测试从未单独改变 wind_speed 而保持其他条件不变,那么风况相关的安全逻辑就没有被充分验证。

四、独立性:测试不能自己证明自己

独立性强调测试活动应由非直接开发人员执行,或至少由不同角色、不同工具、不同视角进行交叉验证。在安全关键领域,独立性通常分为技术独立性、管理独立性和财务独立性。技术独立性要求测试人员不依赖开发人员的口头解释,而依据需求、接口文档和可执行证据进行判断;管理独立性要求测试结论不受进度和成本压力随意修改;财务独立性则保证测试资源不被开发部门完全控制。

独立性不足的典型表现是:开发人员自己写单元测试、自己判定通过、自己关闭缺陷,且没有第三方评审。这样的测试容易陷入“验证自己的实现”而非“验证安全需求”的盲区。

五、鲁棒性、失效安全与容错设计测试

鲁棒性关注软件在异常输入、边界条件、资源不足、通信中断和硬件退化下的稳定程度。失效安全要求系统在发生故障时进入预定义的安全状态,例如悬停、返航、迫降、切断动力或切换到备份通道。容错设计则要求系统在部分组件失效时仍能维持功能或降级运行,例如双余度传感器表决、看门狗复位、任务迁移和冗余通道切换。

这三者的测试重点不同:鲁棒性测试关注“异常下是否崩溃或失控”;失效安全测试关注“故障后是否进入安全状态”;容错测试关注“故障后是否仍能继续完成任务或安全降级”。在无人机场景中,常见测试包括传感器故障注入、通信丢包、执行机构卡死、电源跌落、CPU 过载和看门狗超时。

安全关键软件测试核心概念关系 从安全目标到测试证据的闭环 安全关键软件测试 验证 · 确认 · 追溯 · 覆盖 · 独立 鲁棒 · 失效安全 · 容错 验证 Verification 需求/设计/代码符合性 评审 · 静态分析 · 单元测试 确认 Validation 真实任务与安全目标 场景 · 飞行 · 故障注入 需求追溯 安全目标 → 需求 → 用例 双向链接 · 追溯矩阵 覆盖率 语句 · 分支 · MC/DC 需求覆盖 · 场景覆盖 独立性 · 鲁棒性 · 失效安全 · 容错 独立判定 · 异常稳定 · 安全降级 故障注入 · 冗余切换 · 看门狗 测试证据链:安全目标 → 需求 → 设计 → 代码 → 测试用例 → 结果 → 缺陷闭环

六、案例场景:GPS 失效下的返航测试

假设某无人机安全需求为:“当 GPS 信号连续丢失超过 1 秒时,飞控应在 2 秒内切换至姿态保持模式,并在 5 秒内执行返航或悬停。”测试设计应覆盖以下维度:

  • 验证:检查 GPS 有效性判断函数是否符合设计,模式切换接口是否按规范调用。
  • 确认:在真实飞行或半实物仿真中注入 GPS 丢失,观察无人机是否在安全时间内进入预期状态。
  • 追溯:将该安全需求链接到 GPS 监控模块、模式管理模块、返航控制模块和对应测试用例。
  • 覆盖率:确保 GPS 有效/无效、电池电压高/低、风速大/小等条件组合达到 MC/DC。
  • 独立性:由独立测试团队设计故障注入场景,并独立判定通过与否。
  • 鲁棒性:测试 GPS 数据跳变、间歇丢失、错误定位和通信延迟等异常输入。
  • 失效安全:若返航不可行,系统应进入悬停或受控迫降,而不是继续盲目飞行。
  • 容错:若存在双 GPS 或惯导备份,应验证表决与切换逻辑是否正确。

七、常见误区与复盘

误区 问题 改进措施
把验证当确认 只证明代码符合文档,未证明满足真实安全目标 增加场景测试、飞行试验和故障注入
追溯矩阵形式化 需求与用例链接存在,但内容不对应 定期评审追溯关系,检查双向一致性
只追求语句覆盖率 复合条件中的安全逻辑未被独立验证 引入 MC/DC 和需求覆盖率指标
测试独立性不足 开发自测自判,缺陷被掩盖 建立独立测试角色和第三方评审机制
只测正常流程 异常、边界和故障场景覆盖不足 系统化设计鲁棒性、失效安全和容错测试

关键提醒:安全关键软件测试的目标不是“证明没有缺陷”,而是“提供足够证据,证明在既定安全目标下风险已被识别、控制和验证”。验证与确认、需求追溯、覆盖率、独立性、鲁棒性、失效安全与容错设计测试,必须形成闭环证据链,而不是彼此孤立的测试活动。

八、工程落地要点

安全需求 → 追溯矩阵 → 测试策略 → 用例设计 → 执行记录 → 覆盖分析 → 缺陷闭环
   │           │            │           │           │           │           │
   └─ 安全目标  └─ 双向链接   └─ 独立评审  └─ MC/DC    └─ 可复现   └─ 需求覆盖  └─ 回归验证

在无人机安全关键软件项目中,建议将上述概念固化为测试门禁:需求未追溯不进入测试设计;关键安全需求未达到 MC/DC 不通过覆盖率评审;故障注入场景未覆盖失效安全和容错路径不通过系统测试;测试结论未经独立角色确认不关闭安全缺陷。只有这样,测试才真正成为安全保证的一部分,而不是进度表中的一道形式化环节。