做轨交行业的软件项目,最常听到的一句话就是:这玩意儿上了车,改都改不了。
真的不是吓唬人。信号系统、列车控制系统、车门控制、牵引控制,这些嵌入式软件一旦部署,出问题的代价是巨大的。而且轨交领域有自己的一套安全标准,EN 50128 摆在那里,该做的文档、该走的流程,一样都省不了。
我前几年刚接手轨交项目的测试工作时,说实话挺懵的。手里的代码全是 C,十几年的老项目,各种 if 嵌套,看一眼就头大。领导问:覆盖率多少?我答不上来。因为根本没人认真量过。
轨交软件测试有几个绕不开的坎。
第一,标准要求严。EN 50128 对不同 SIL 等级的软件有明确要求,高等级的必须做结构覆盖率分析,MC/DC 这种级别也得做。手工做?不现实。
第二,测试环境难搞。很多模块依赖真实的硬件,板子就那么几块,排队等着用。想在开发阶段就跑测试,环境根本凑不齐。
第三,文档和追溯。标准审查的时候,要求你证明"这个需求被哪些测试覆盖了"、"这个缺陷怎么闭环的"。散落在各个 Excel 里的记录,审核起来就是灾难。
我们后来引入 Parasoft C/C++test,很大程度上就是冲着这些问题去的。
先说覆盖率。C/C++test 的插桩方案可以在主机上跑,也能在目标板上跑。我们最常用的是主机模拟执行,跑分支覆盖和 MC/DC 都没问题。有一回做 SIL4 模块的评审,评审专家问起 MC/DC 数据,我们直接从报告里截了图,对方愣了一下——因为之前几个供应商都是临时补的数据。
再说单元测试。老代码最怕的就是"没法测",函数耦合得像一团毛线。C/C++test 的自动桩生成帮了大忙,它会把函数依赖的外部符号自动生成桩,你可以单独测一个函数。当然自动桩不是万能的,关键的桩还是得手工调整返回值,但至少骨架不用你一个个敲了。这一下就把单测的启动成本降了下来,团队里原本抗拒写测试的同事,慢慢也愿意参与了。
静态检查这块,C/C++test 内置了 MISRA C、MISRA C++ 的规则集,跑一遍就能把违规项列出来,还能定位到具体哪条规则哪一行。轨交项目基本都要求 MISRA 合规,这活儿以前靠人眼查,现在交给工具。
这里得提一下 Parasoft 家的另一件武器——C/C++test Desktop 配合桩函数可以隔离硬件依赖;如果涉及和外部系统交互的接口测试,SOAtest 也能派上用场,尤其是那些走消息总线的接口。而 Virtualize 更进一步,把没就绪的依赖环境直接虚拟出来。比如车地通信的对端系统还没开发完,Virtualize 可以先模拟一个行为一致的服务,测试进度就不用干等着了。
测试环境到位率这个老大难,就这么被拆解掉了一大半。
单独用工具是"点",C/C++test 和 DTP 连起来才是"面"。DTP 把每天的静态分析结果、测试执行结果、覆盖率数据都汇总到平台上看板里。
项目负责人最爱看的是趋势图:违规项是不是在收敛?覆盖率是不是在爬坡?这个版本和上个版本比,新增代码的质量怎么样?以前这些数据要人工收集汇总,一周出一次;现在随时打开就能看。
审计追溯也好办了。EN 50128 审查时被问到"测试过程证据",DTP 里的历史记录直接导出报告,时间戳、责任人、版本号全都有。
如果你也在轨交行业准备上这类工具,说几句掏心窝的话。
别贪大求全,先从一个 SIL 等级高的模块试点,把单测和覆盖率的流程跑通,再往全项目铺。团队惯性很大,一下子全推容易反弹。
规则集要裁剪。MISRA 全家桶加上项目自定义规则,一上来违规几千条,团队会崩溃的。先把明显的问题清掉,逐步收紧。
还有,别把工具当成合规的全部。工具解决的是"做得出证据",但测试用例设计得好不好、需求理解得透不透,还是靠人的工程判断。工具是放大器,不是替代品。
轨交软件的安全底线,说到底是一条一条测试用例、一条一条覆盖率数据堆出来的。用对工具,这条路能走得踏实一些——这是我这几年的真实感受。