功能安全项目一旦进入评审阶段,临时从工具里匆匆导出一份扫描报告,往往是不够的。C/C++test这个工具,可以覆盖静态分析、单元测试、结构覆盖率以及需求的追踪,而Parasoft也提供了面向ISO 26262的合规资料和工具鉴定方面的支持。但真正需要准备出来的,其实是一条完整的证据链:这次到底用了什么规则、具体分析了哪些代码、发现的问题是怎么处理的、测试执行的结果怎样、覆盖率有没有达到预定的目标,以及需求和测试之间能不能做到互相追溯。这几块少了哪一样,评审的时候都可能被问到答不上来。
一、ISO 26262相关的证据怎么整理
整理这些证据的时候,不要只在某个文件夹里随便建一个报告目录就完事了。比较清晰的做法,是按照项目基线、静态分析、动态测试和追踪关系这几块来分层存放东西,这样后面遇到问题再回头去查的时候,思路会清楚很多,不至于在多个版本的报告里来回翻找。
1、先把分析的基线固定下来
把代码对应的分支、提交号、构建编号这些信息都记录下来,另外编译器用的是哪个版本、C/C++test本身是什么版本,还有测试配置的名称和执行的时间,也一同写清楚。用到的规则配置文件也要单独保存一份,不要以为默认配置永远不会变。等将来项目升级了规则集,或者更换了编译环境之后,回头再去看当时那份报告,为什么里面的数据会跟现在不一样,这些东西就能够用来做对比了,不然根本对不上号。
2、把静态分析的结果整理好
静态分析这部分,要保存下来的东西包括选用的规则集、查出来的违规清单、被抑制掉的那些问题记录、针对某个问题做出的偏离说明,还有后续的整改结果。在ISO 26262的项目里面,通常还会结合MISRA C、MISRA C++或者AUTOSAR C++14这些编码规范一起来检查,输出项会更复杂一些。按照Parasoft的说明,静态分析的结果里面,可以包含规则违规的信息、代码复杂度以及一些质量度量数据,这些数据很适合用来做历史归档,也方便审核人员去检查动态变化。
3、把单元测试和覆盖率的证据整理出来
单元测试这一块,要保留的有测试用例本身、每次测试给的输入数据、对应的预期结果、最终跑出来的实际结果,还有失败的那些记录,以及回归测试的结果。覆盖率则要区分清楚,是语句覆盖、分支覆盖,还是MC/DC这一类更严格的标准,不能笼统地写一个数字。同时还需要把覆盖率是在什么环境下采集到的说明清楚,因为C/C++test既支持在宿主机Host环境中收集覆盖率,也支持在目标机Target环境中收集,而且还能把不同测试阶段得到的覆盖历史数据给累计起来,这块的说明不能省掉。
二、ISO 26262相关的报告怎么导出
报告的导出可以通过图形界面去做,也可以放到自动化流水线里面来操作。对于一个正经的正式项目来说,一般情况下建议这两种方式都保留一下:桌面端导出的报告,方便在日常工作里临时复核一下某些问题;而命令行方式导出来的,则更适合用来形成稳定的归档文件,确保每次出的报告格式都是一致的。
1、从图形界面这边导出
在分析跑完之后,在【Test Progress】面板上面点击【Generate Report】这个按钮,就会进入【Report&Publish】的窗口。在这个界面里,需要先设置一下报告保存的目录,确认已经启用了生成报告的那个选项,然后再根据需要选择要不要自动打开浏览器去预览。如果希望看到更加细致的单元测试记录,那就要在测试配置中,把测试执行的明细条目和覆盖率的明细条目都给打开,否则导出来的报告里可能就只有概要信息,评审时拿去用就不太够看了。
2、从命令行那边来导出
在持续集成的流水线里面,可以用【cpptestcli】这个命令来执行分析,并且在命令后面带上【-report】参数,用它来指定报告输出的目录在哪里。如果同时还需要把分析的结果上传到DTP集中管理平台,那就再加上一个【-publish】参数,这样本地报告和云端数据就能一起更新。按照官方的文档说明,【-report】这个参数专门负责生成本地的报告文件,而【-publish】则负责把结果推送到DTP上面去,两个功能的用途不一样,可以搭配着用。
3、设置报告的输出格式
可以在localsettings这个配置文件里面,写上【report.format=html,pdf】这样一行,这样一次分析就可以同时把HTML格式和PDF格式的报告都生成出来,不需要再分开跑两遍;也可以用【report.location】来固定好归档的目录位置,免得每次弹出来的保存路径都不一样。HTML格式的报告比较适合开发人员平时在电脑上翻阅细节,而PDF格式的则更适合打印出来放进正式评审材料里去。用配置文件把这些写死之后,还能让团队里的报告规则保持一致,减少每台电脑因为手动设置不一致,导致导出来的报告格式五花八门的情况。
三、证据归档时怎样避免后期返工
当报告导出来以后,不能就放在那里不管了,还要再花时间去检查一下,这些证据相互之间是不是真的能对应得上。有些时候文件确实生成了很多,可彼此之间没有建立起半点联系,到了评审的时候,还是会被反复要求补材料,因为审核人员无法从孤立的文件里看到整个追溯链路。
1、把需求和测试连在一起看
需求编号要能够一路追到测试用例、测试的执行结果,以及最终达到的覆盖率数字。Parasoft的DTP平台,可以把需求管理系统里面的标识符,跟静态分析的结果、覆盖率的数据、单元测试和集成测试的结果都关联起来,并且在一个追踪矩阵当中,把这些双向关系展示出来,这样当审核人员问“这条需求有没有测过”的时候,就可以直接从矩阵里找出来,而不是只能靠口头解释。
2、别只留通过的记录,失败和偏离也要保存
不要只把那些全部显示通过的漂亮报告拿去归档,这种做法在功能安全审核里是很容易被看出来的。测试失败的记录、规则被偏离的声明、某个问题为什么可以被关闭的依据,还有重新验证之后的结果,这几样东西反而更可能是审核人员关心的重点,他们往往更想看到某个问题是怎么被处理掉的,而不是一张干干净净、看不到任何错误的截图。
3、按照发布的节点去建立证据包
每一次正式发布的时候,都单独建一个目录,把这一版的规则配置、分析报告、测试报告、覆盖率报告、追踪矩阵、工具本身的版本信息,还有构建的相关信息都存放在一起,并且做好标记。不要把好几个版本的报告全都混在一个文件夹里,这样到了后面,根本没有办法快速确认某一组报告到底对应的是哪一版代码,追溯起来就变得非常困难。
总结
关于C/C++test在ISO 26262项目里的证据怎么整理,以及报告该怎么导出,整个处理的顺序可以大致概括为:先把代码和工具的基线固定下来并记录清楚,然后分层去整理静态分析的规则和违规记录、单元测试的执行与覆盖情况,还有需求和测试之间的追溯关系;报告则可以通过【Generate Report】这个图形界面的方式,或者【cpptestcli-report】这条命令行来导出,有集中管理需求的时候再上传到DTP上。证据包最好按照发布的版本一个一个地去归档,失败记录和偏离说明也一并放进去保留好,前期多花这点心思把东西理顺了,到了后期的评审阶段就会省掉很多来回返工的麻烦。