| 编辑推荐: |
本文主要介绍了基于Testbed的车载ECU软件集成测试方法研究相关内容。希望对你的学习有帮助。 本文来自于微信公众号汽车电子与软件
,由火龙果软件Alice编辑,推荐。 |
|
摘 要
在软件开发初期进行代码级集成测试可以提早发现并修复潜在的错误和缺陷,减少后期修复成本。ISO 26262中要求做基于需求的软件测试,但在目前的车载软件集成测试中,更多关注代码结构覆盖率,缺乏对软件需求和功能的验证。文章依托Testbed工具实现了一种新的软件集成测试方法,通过功能分解、线程划分、调用路径分析以及设计参数等,完成了基于需求的用例设计,保证对软件需求的100%覆盖与追溯。此外,为了进一步覆盖系统运行的特殊工况,提出了可变参数循环执行用例的方法。通过监测用例多次执行的路径和语句被执行次数,在代码层面实现了故障注入测试。最后,在车载拖车控制器软件上对该方法进行验证,结果表明,该方法具有很强的实用性和高效性。
传统汽车研发中车载电子控制单元(Electronic Control Unit, ECU)软件验证主要依赖硬件在环测试和实车测试。在正式的样车试制前把系统集成至测试台架中,模拟各类测试环境,按照相关测试标准对汽车的电子系统性能和功能进行测试。自动驾驶领域出现了场景仿生与数字孪生测试,场景仿真测试主要依托高精度仿真平台,在虚拟环境中重现复杂的驾驶场景。这些需要依赖一定的硬件环境和仿真模型,费用昂贵,并且无法在软件设计初期执行。
近年来,随着各主机厂逐步开始自研软件,在代码层面做集成测试也被引入到现有测试体系。目前,市场上比较主流的集成测试工具有LDRA
Testbed、VectorCast、SmartRocket等。其中,LDRA Testbed功能强大,广泛应用于汽车电子、航空航天和医疗等领域。该工具提供了静态测试、单元测试、集成测试和代码覆盖率分析等一系列功能,是开发高安全性、高质量软件产品的重要工具。
行业内做集成测试主要有自顶向下集成测试、自底向上集成测试等类型,其中,前者从最主要模块开始,按功能减弱顺序向系统中增加模块;后者是从功能性比较弱的模块开始,按功能层次增强的顺序向系统中增加模块,逐渐实现整个系统的集成[3-5]。
01 车载软件集成测试
1.1 软件集成测试概述
集成测试可以脱离外部物理环境来验证代码内部功能逻辑,其测试对象为软件的功能模块(函数单元),目的是检验软件模块实现的正确性以及模块之间交互的正确性。执行集成测试需要动态运行代码,监测函数模块之间的调用关系、控制流、数据流等,主要测试指标包括函数覆盖率、调用覆盖率、语句覆盖率和分支覆盖率等[6]。其中,函数调用覆盖率(Function
Coverage)是已执行的软件函数的百分比,调用覆盖率(Call Coverage)是文件中函数调用次数的百分比。
1.2 基于需求的集成测试方案
结构覆盖率只能表明软件有无死循环、不可达代码以及分支进入条件错误等结构性问题,若要发现与具体使用场景相关的功能问题,需开展更深层次的测试。根据《道路车辆
功能安全 第6部分:产品开发 硬件层面》(ISO 26262-6-2018)(下文简称“标准”)相关要求,软件集成测试包含基于需求的测试、接口测试和故障注入测试等[7]。
本文在传统结构覆盖率基础上设计了一种新的测试方案,即基于需求的集成测试。该方案同时关注代码结构覆盖率和需求覆盖率,完整测试过程如下:
1.基于需求的功能划分
基于需求的集成测试,首先要根据软件架构设计说明书划分功能层级。车载软件迭代速度快,效率优先,所以适合用广度优先自顶向下集成测试法[8],自然地做到逐步求精,在测试初期,测试者就看到系统功能的整体框架。
2.确定集成路径深度
为避免因路径深度不同导致的多个入口函数的产生,需要根据所划分的功能模块和集成策略确定每个功能模块的入口函数。如果选择自顶向下的测试策略,那么入口函数则选择功能模块的顶层函数。
3.设计测试用例
基于需求的集成测试,所有测试用例必须能完整覆盖软件需求中的功能项,并且测试用例与功能项(测试需求)之间必须建立追溯关系。
4.设计测试参数
测试用例设计完成后,要通过对代码中全局变量和函数实参赋值来动态运行。所以,合理设计参数后,用例可以沿着不同的调用路径执行代码,最终实现全路径覆盖。
5.分析代码执行路径
测试用例执行完成后,需要通过分析数据判断软件需求是否被验证。除了函数覆盖率及调用覆盖率,基于需求的集成测试还需通过函数语句的被执行次数来验证测试用例是否执行了期望的调用路径。
02 应用案例
本章节以乘用车拖车控制器为例,验证基于需求的软件集成测试方案,测试工具为LDRA Testbed。拖车控制器安装在前车上,用于控制电动拖车钩伸缩、后车灯光等。其主要功能包括信号传递、电源管理、拖车钩控制、灯光控制、刹车控制、倒车辅助等。
2.1 基于需求的功能划分
本文将拖车控制器软件功能划分为四个层级,如图1所示。拖车模式功能项作为顶层功能模块,在此基础上合并需求中的独立条目,划分第二层级的小功能项:模式连接检测、拖车灯状态检测、拖车钩堵转报保护、拖车钩防夹;第三层级以同类型的多个操作项作为一个任务集合;第四层级参照实车测试,以能够组成一个独立可观测的行为作为最小颗粒度功能。本文选择灯光控制相关的五个功能场景开展测试,并且将根据上述功能层级划分情况设计具体的测试用例。
图1 拖车控制器软件功能层级划分图
2.2 确定集成路径深度
依据功能划分层级,本案例设计最大集成深度为四层。若调用路径超过四层,则在调用路径顶部及中间各设置一个入口函数,叠加测试。
1.分析任务调用关系
为了将基于需求的功能模块映射到程序中,需要明确任务调用关系。拖车控制器软件中主要包含两个并行线程:人机交互(Human-Machine
Interaction, HMI)任务线程和灯光线程。其中,HMI任务线程负责拖车模式判断和灯光同步,灯光线程负责灯光自检。具体运行过程如图2所示,HMI任务线程通过扫描接口连接事件判断是否进入拖车模式,并在获取到进入拖车模式事件后发出“进入拖车模式标志位”;灯光线程扫描到该标志位后立即开始灯光自检任务,并在自检完成后发出“灯光自检完成标志位”;当HMI任务线程扫描到该标志,则进入灯光同步任务。
图2 拖车控制器模块功能任务交互
两个线程独立运行,通过在同一全局变量数据流上获取不同时段的值,形成任务优先次序。由于函数之间没有直接调用关系,所以这里依据线程将拖车控制器划分为两大功能模块,并分别使HMIMain和LightMain作为两个模块的入口函数,如图3所示。
图3 顶层任务调用关系
2.设计模块执行路径
测试用例覆盖的代码范围为测试路径,在测试初期需要对测试路径进行设计,并在测试用例执行结束后基于期望结果验证路径的准确性。拖车控制器软件包括与硬件相关的驱动层程序以及与控制逻辑相关的应用层程序。本节测试路径设计将按照2.1章节中划分的功能模块,对应用层程序进行集成测试,这里将与硬件相关的信号获取函数与信号值设置函数全部打桩处理。
灯光同步任务与转向灯、制动灯、位置灯、后雾灯和倒车灯等5个灯光模块相关,且均被拖车灯光事件扫描函数ScanTrailerLightEvent调用。所以本文将ScanTrailerLightEvent函数作为灯光同步的公共入口函数,测试某个灯光模块时将其余四个模块被调函数全部打桩。以后雾灯灯光同步模块测试为例,为了层层调用相关函数执行测试,在Testbed软件中对扫描后雾灯光事件函数ScanTrailerLightBFogLightEvent、打开拖车灯动作函数OpenTrailerLight以及灯光控制逻辑函数CtrlTrailerLight均不打桩,最终通过ExecuteCMD函数调用不同参数来实现灯光点亮和熄灭。通过分析确定了后雾灯模块主要的调用路径,同时也是功能是否被成功实现的观测路径,如图4所示。
图4 后雾灯同步模块函数调用关系
2.3 设计测试用例
本节根据标准中推荐的用例设计方法,设计拖车控制器软件功能测试用例[9],如表1所示。
表1 软件集成测试的用例设计方法
注:ASIL(汽车安全完整性等级, Automotive Safety Integrity Level);“++”表示该方法强烈推荐用于已识别的ASIL等级;“+”表示该方法推荐用于已识别的ASIL等级。
按照表1用例设计方法,对每个功能需求进行层次性的场景分解,直至将所有功能需求用条目化方式罗列出来。软件需求中后雾灯灯光同步的控制逻辑如图5所示。
图5 后雾灯灯光同步逻辑
通过分析后雾灯同步的软件需求,形成5条测试需求(tr):
tr1:灯光自检未完成,不能进入灯光同步;
tr2:灯光自检完成,拖车控制器收到左车身控制器的后雾灯点亮报文,控制拖车后雾灯点亮;
tr3:灯光自检完成,拖车控制器收到左车身控制器的后雾灯熄灭报文,控制拖车后雾灯熄灭;
tr4:灯光自检完成,拖车控制器收到来自左车身控制器的后雾灯无效报文,保持上一状态;
tr5:灯光自检完成,拖车控制器未收到来自左车身控制器的后雾灯报文,控制后雾灯保持上一状态。
设计5条测试用例(tc),分别验证以上5条测试需求:
tc1:验证首次自检未完成不能执行灯光同步;
tc2:验证正常点亮后雾灯;
tc3:验证正常熄灭后雾灯;
tc4:验证点亮状态收到无效报文保持点亮;
tc5:验证点亮状态左域控制器掉线,控制后雾灯保持点亮。
以上5条用例,覆盖了后雾灯灯光同步的所有测试需求,对需求的覆盖率100%。其中tc5属于故障注入测试。软件需求项分别与测试需求、测试用例之间形成一对一、一对多的关系,所建立的测试用例追溯关系如表2所示。
表2 测试用例追溯关系
2.4 设计测试参数
本节将详细介绍在Testbed软件中如何设计tc5用例的参数:
步骤1:点亮后雾灯;
步骤2:设置左域控制器断线故障;
步骤3:发送熄灭后雾灯指令。
根据以上步骤,需要同一测试用例连续运行两次:第一次左域控制器信号正常,向拖车控制器发送点亮指令(Light_On);第二次左域控制器信号故障,向拖车控制器发送熄灭指令(Light_
Off)。具体参数设计如表3所示。
表3 tc5对应参数列表
完成测试用例参数设计后,于Testbed软件中进行相关配置:新建测试用例,设置用例重复执行次数“Number
of Repetitions=2”;在“Variable I/O View”界面输入全局变量的值;在桩函数管理界面中输入信号采集函数SigMgrGetSig的返回值和函数实参的值。完成以上参数设置,一个可执行的测试用例则设计完成。
2.5 用例执行及执行路径的分析
用例参数设置完成后,从入口函数开始执行。根据本章2.2节中设定的路径,选定ExecuteCMD函数作为最终观测点。测试结果同时关注两个条件,即结构覆盖率完整和用例执行路径正确。
2.5.1 结构覆盖率分析
如图4所示,后雾灯同步模块涉及5个函数(置灰部分),其中ExecuteCMD函数位于驱动程序中,其余4个分布在LightTrailer.c文件中。
仅执行用例tc5之后,整个LightTrailer.c文件的调用覆盖率为6%,调用次数为12,同一个函数在不同位置被重复调用,算多次调用;函数覆盖率为12%,被调用的函数个数为4,即除了Excute-CMD以外其余4个函数都被调用。
通过调用覆盖率、函数覆盖率可以证明函数之间接口可以正常调用,没有出现函数异常调用。当LightTrailer.c中所有功能执行完成后,调用覆盖率和函数覆盖率预期为100%。
2.5.2 需求覆盖率分析
测试需求tr5是验证点亮状态后左域控制器掉线,控制后雾灯保持点亮。需要测试用例tc5连续运行两次,两次运行的执行路径如图6所示。
图6 用例tc5执行路径
用例执行第一次,左域控制器非掉线状态,正常点亮后雾灯,所有函数均被调用。用例执行第二次,左域控制器掉线状态,执行Scan
Trailer- LightBFogLightEvent函数后因为故障,保持上一状态。所以ScanTrailerLightEvent、ScanTrailerLight-
BFogLightEvent函数预期执行2次,实际路径追溯结果如图7和图8所示。
图7 函数ScanTrailerLightEvent执行次数
图8 函数ScanTrailerLightBFogLightEvent执行次数
CtrlTrailerLight函数的语句覆盖报告如图9所示,其实际执行次数为1次,符合预期结果。其中拖车后雾灯驱动开启指令ExecuteCMD(0x2-
407010100000000)语句执行1次,拖车后雾灯驱动关闭指令ExecuteCMD (0x2407010000000000)语句执行0次。这表明左车身控制器断线以后,控制后雾灯保持点亮,所以用例tc5执行结果符合预期,测试需求tr5验证通过。当所有用例执行完成后,后雾灯灯光同步的控制逻辑这条软件需求覆盖率应该达到100%。
图9 灯光控制逻辑执行结果
03 结束语
本文使用Testbed工具对拖车控制器软件进行了基于需求的软件集成测试。通过对软件架构设计说明进行分析,完成了对功能模块的拆解。进一步将功能模块映射到软件程序中,确定了测
试的期望路径、入口函数和观测点,完成对软件代码的模块划分。同时,在Testbed工具中建立测试用例,结合功能模块合理设计参数,在代码层面上实现了故障注入测试功能项的验证。该方法不借助硬件环境,在软件开发早期阶段可以完成核心逻辑功能的测试,极大提升了软件迭代效率,保障了项目交付进度。 |