高安全软件代码覆盖率自动化测试工具应用
2021-11-19沈雷,林娇娇
高安全领域对电子产品的安全性分析提出了具体的要求。作为运行在高安全系统中的软件,必须在测试过程中进行代码覆盖率分析,通常要求MC/DC覆盖率达到100%。本文分析了常用单元测试软件对C语言开发的嵌入式项目进行自动化单元测试的覆盖率情况,通过比较得出单元测试的最优解决方案。
0 引言
随着工业互联网技术的发展,嵌入式系统的应用越来越广。嵌入式软件单元测试成为嵌入式系统功能安全测试的一项重要工作。通过单元测试往往能够发现代码中潜在的逻辑缺陷及隐藏的运行错误。高安全领域,如航天、轨道交通、核电等行业对产品的安全性有更高的要求。运行在高安全系统中的软件,在测试过程中必须进行代码覆盖率分析,MC/DC覆盖率一般要求达到100%。
从软件代码覆盖率可以详细了解被测代码的测试覆盖情况,通过分析明确如何补充测试用例去验证未执行的代码;或者找出代码未被执行的原因,帮助发现程序中的潜在缺陷,提高软件质量。
为了大幅提高测试人员的工作效率,保障软件测试质量,并且将测试人员从繁重的用例编写任务中解脱出来,很多单元测试工具能够自动生成满足语句、分支、MC/DC准则的测试用例,本文对几个常用单元测试软件Testbed、Cantata、SmartUnit的单元测试覆盖率情况进行了分析。
1 工具说明
Testbed、Cantata、SmartUnit是目前嵌入式领域常用的单元测试软件,它们都通过了国际上功能安全认证,符合IEC 61508-3∶2010(工业通用)、EN 50128∶2011(轨道交通)、ISO 26262-8∶2018(汽车电子)等行业功能安全标准对单元测试工具的要求。
1.1 Testbed
Testbed软件测试工具功能较强大,适用于嵌入式软件静态分析及单元测试,较广泛地应用于国内各大研究机构、软件测试部门。
Testbed可以自动生成测试驱动,在代码更新后能对需要修改的测试数据进行跟踪和报告,便于回归测试。工具提供图形界面和命令行两种操作方式,支持文本和图形化方式查看代码覆盖率;有助于测试结果的分析和白盒测试用例设计。
通过Testbed可实现自动化单元测试,提高单元测试效率。它能够提供包括语句、分支、调用、MC/DC、测试路径(LCSAJ)、目标码等覆盖率指标,满足不同安全等级软件的覆盖率要求。
1.2 Cantata
Cantata提供基于Eclipse的完整测试开发环境,可以对C/C++代码进行单元和集成测试,自动生成用例、测试执行后对测试结果进行评估并生成测试报告等。
Cantata可以自动生成调用接口控制(Stubs、Isolates和Wrappers)测试脚本,用户可以通过图形界面设定变量和返回值的期望值,或者直接编辑测试脚本,即可运行测试。测试脚本管理器可以实现脚本的复用。
Cantata可以自动生成测试用例的驱动函数和桩函数,自动判定实际结果是否和期望结果一致。工具能记录测试过程并输出到文件,包括全局变量、参数和返回值、函数调用顺序等详细信息,通过分析这些信息可以对失败的用例进行准确的定位,进而找到测试失败的根本原因。
可通过Stubs/Isolates模拟或通过Wrapper真实调用来实现任意调用(编译单元边界内或边界外),自动检查调用接口的参数/返回值,验证真实调用顺序或时间是否匹配。使得测试更加充分灵活,将被测单元从系统中完全独立出来,实现对函数的完全控制。
Cantata支持函数入口点、语句、调用返回、判定、条件和MC/DC覆盖等。
1.3 SmartUnit
SmartUnit工具是依托国家可信嵌入式软件工程技术研究中心所研发的一款智能化单元测试工具,根据需要能对C语言自动生成满足分支、语句、边界及 MC/DC覆盖准则的测试用例,实现全自动化单元测试。
SmartUnit采用人工智能算法,利用自动推理与符号执行技术,分析程序路径,生成测试用例并执行测试。SmartUnit 分析的数据包含了被测函数形参、全局变量、桩函数以及桩函数形参等数据,全面涵盖了单元测试的用例数据。
2 工具比对
在某嵌入式实时操作系统功能安全认证项目中,分别采用Testbed、Cantata和SmartUnit工具对被测操作系统的源码进行单元测试,并获取代码覆盖情况。
2.1 测试环境
根据测试计划,单元测试运行在工具安装平台,使用工具自带的编译器完成代码的编译运行,如表1所示。
表1 测试环境Tab.1 Test environment
各工具使用的编译器的版本不一致,但对测试过程中单元测试代码语句覆盖情况统计并无明显影响。
2.2 测试结果
不管使用什么工具,单元测试中代码的覆盖率都取决于测试用例的设计。为了达到MC/DC100%覆盖要求,测试人员需要对分析代码结构,设计不同等价类的输入参数组合,以实现各条路径及分支的覆盖,最终使得所有用例的组合覆盖率尽可能达到MC/DC100%覆盖,满足测试要求。
虽然在安全软件中不建议指针的使用,但由于操作系统软件的特殊性,指针的使用难以避免,被测源码中存在大量结构体及指针,如果人工直接分析代码设计用例,效率很低。单元测试工具的自动用例生成功能对提高测试效率有着极大的帮助。
项目部分源码使用不同工具自动生成单元测试用例执行后所得到的覆盖率的对比情况见图1。
图1 单元测试用例执行覆盖率统计Fig.1 Unit test case execution coverage statistics
Testbed工具的Extrme test功能能够自动生成测试用例,但所生成的用例主要是针对边界值及异常测试,对于MC/DC覆盖率并没有太大作用。SmartUnit 和Cantata软件自动生成的单元测试用例MC/DC覆盖率较好。经过数据对比发现Cantata工具自动生成用例的覆盖率表现最佳,SmartUnit软件所生成用例的覆盖率优于Testbed工具,但该软件对被测代码的部分语法支持并不完善。考虑项目执行效率,最终选定Cantata工具作为项目单元测试工具。
2.3 工具问题的解决
2.3.1 自动生成用例失败的解决
在使用Cantata工具执行单元测试过程中,工具在对部分源码生成测试用例时会进入无响应状态,等待很长时间也无法得到生成结果。如:semaphore_create函数。经分析,发现是因为工具对特定语法的支持不完善。经过反复试验,得到如下解决方案:
(1)修改源代码,通过定义全局变量,先生成测试脚本。
(2)后续按正常步骤生成测试脚本,根据测试需要对测试脚本进行修改。
(3)将源代码复原,然后再运行测试脚本。
2.3.2 生成用例运行结果失败的解决
工具自动生成的用例有可能出现桩函数预期返回值与实际结果不符的情况,从而导致用例运行结果为不通过。此时可以修改该桩代码实例,指定正确的预期返回值结果,与期望结果匹配。
3 总结
经过项目实践,得出如下结果:
(1)Testbed、Cantata、SmartUnit三个工具对嵌入式C软件代码覆盖率测试都可以提供充分的支持。工具自动化测试用例生成后再通过人工补充用例设计,最终软件代码覆盖率均能达到MC/DC100%覆盖要求(部分软件代码由于设计缺陷,存在不可达路径,测试执行中不可能得到MC/DC100%的结果,对此类代码应采用人工走查方式进行分析说明)。
(2)通过对比各工具自动生成用例的执行结果,目前版本下Cantata工具单元测试自动生成用例执行结果的MC/DC覆盖率较高。作为国产研制的嵌入式软件单元测试工具,SmartUnit的单元测试用例MC/DC覆盖率结果与Cantata相差不大,但对被测代码的语法支持能力稍差,建议作为项目的备选方案。
(3)各工具版本都在不断更新,新版本发布后需要重新进行工具的对比研究。