评估模型与代码覆盖率之间的差异
此示例演示了如何使用 Simulink® Test™ Manager 分析模型覆盖率和生成代码覆盖率,并调查结果中的差异。有关如何在不使用 Simulink Test 的情况下分析代码覆盖率的信息,请参阅使用 Simulink Coverage 收集代码覆盖率度量和软件在环代码覆盖率。
在分析代码覆盖率时,代码覆盖率结果可能与模型覆盖率结果不完全一致。
尽管 Embedded Coder 的目标是生成与模型行为相同的代码,但 Simulink® 模型和 C/C++ 代码在抽象层次上存在根本差异。Simulink 模型是期望行为的高级表示,而 C 和 C++ 是低级编程语言。由于这种差异,行为的实现方式不同,可能导致结构不同。
模型和代码覆盖率结果可能存在差异,原因可能包括:
语句覆盖率与模块执行覆盖率不同。例如,Stateflow® 图和转移不会获得模块执行覆盖率,但从它们生成的代码会获得语句覆盖率。此外,由于一个模块的实现通常包含多个代码语句,因此一个模块的执行结果通常会对应生成代码中的多个语句.
模型覆盖率中的“整数溢出饱和”度量在代码覆盖率中成为决策结果。
在 MATLAB® Function 模块内部的函数调用,在模型覆盖率中会报告为一个决策,但在代码覆盖率中会报告为函数调用覆盖率。
Embedded Coder 会尝试优化生成的代码,以消除不必要的执行分支。如果你的模型中存在死逻辑,Embedded Coder 可能会从生成代码中移除这些逻辑。
默认情况下,Embedded Coder 会执行表达式折叠优化,即将多个决策折叠为一个更复杂的决策。此优化可能会导致决策、条件和多条件死代码覆盖率 (MCDC) 的差异。有关详细信息,请参阅Minimize Computations and Storage for Intermediate Results at Block Outputs (Embedded Coder)。
设置覆盖率
此示例模型 CruseControl.slx 是一个实现简单巡航控制逻辑的 Stateflow 图。
此示例包含一个 Simulink® Test™ 测试文件,该文件包含一组测试用例,可实现 100% 模型覆盖率,随后利用这些测试用例通过软件在环 (SIL) 仿真模式分析代码覆盖率。
打开 Simulink 测试管理器并加载测试用例。
sltestmgr
testFile = sltest.testmanager.load("CruiseControl_Tests.mldatx");运行测试套件
使用 sltest.testmanager.run 运行测试套件。不提供任何输入将运行所有已加载的测试。
testFile.run();
在测试管理器中查看覆盖率结果
在测试管理器中,点击结果和工件。展开结果,然后选择 CruiseControl_Tests > CruiseControl_TestSuite > Model-in-the-loop Tests。然后,在聚合覆盖率结果下,通过点击创建聚合覆盖报告图标
来生成模型覆盖率报告。在这组测试中,模型覆盖率报告器显示决策覆盖率、条件覆盖率和 MCDC 覆盖率均为 100%。
在左侧窗格中,选择 CruiseControl_Tests > CruiseControl_TestSuite > Software-in-the-loop Tests。在聚合覆盖率结果下,通过点击创建聚合覆盖报告图标
生成代码覆盖率报告。这些测试使用相同的测试用例和测试输入,但代码覆盖率报告显示决策覆盖率为 97%,条件覆盖率为 96%,MCDC 覆盖率为 91%。要理解造成这种差异的原因,需要进一步分析覆盖率报告。
审查代码覆盖率报告
在启用了覆盖率结果突出显示的情况下查看模型。在测试管理器中,进入 Software-in-the-loop Tests 结果,在聚合覆盖率结果下,点击要分析的模型名称 CruiseControl,打开模型的覆盖率详细信息窗格,并突出显示具有覆盖率结果的模型。双击以进入 Compute target speed 图。

在覆盖率详细信息窗格中,滚动至详细信息部分。详细信息部分的第一部分显示了整个系统的覆盖率结果。在模型覆盖率报告中,所针对的模型为 CruiseControl,而在代码覆盖率报告中(即当前覆盖率详细信息窗格显示的报告),所针对的文件为 CruiseControl.c。模型覆盖率和代码覆盖率报告分别显示如下覆盖率结果:
覆盖率度量 | 模型覆盖率结果 | 代码覆盖率结果 |
|---|---|---|
决策 | 100%(38 个结果,总共 38 个) | 97%(38 个结果,总共 39 个) |
条件 | 100%(32 个结果,总共 32 个) | 96%(69 个结果,总共 72 个) |
MCDC | 100%(16 个结果,总共 16 个) | 91%(20 个结果,总共 22 个) |
执行 | 不适用 | 不适用 |
语句 | 不适用 | 100%(89 个语句,总共 89 个) |
函数 | 不适用 | 100%(5 个函数,总共 5 个) |
函数调用 | 不适用 | 100%(3 个函数调用,总共 3 个) |
通过比较结果,您可以发现决策、条件和 MCDC 覆盖率在代码覆盖率报告器中具有更多的覆盖率结果。
审查具体差异
在 Simulink 画布中,有两个转移未被覆盖。点击下方的转移,[hasChangedTo(CoastSetSw,true)]。在模型覆盖率报告中,您会看到一个经过分析的决策,该决策有两个可能的结果,这就是决定是否进行此次转移的最终决策。然而,在代码覆盖率报告中,您会看到一个经过分析的决策,该决策有两个可能的结果;两个经过分析的条件,每个条件都有两个可能的结果;以及两个 MCDC 结果。

当模型以代码覆盖率结果高亮显示时,点击转移线可跳转至代码覆盖率报告中的相应代码部分。如果您向上滚动至详细信息部分,即可查看覆盖率表格。在本例中,第 3.18 节是与本次转移相关的部分。

分析的条件和 MC/DC 分析表格说明了代码覆盖率报告中出现新结果的原因。hasChangedTo 运算符在模型覆盖率中会报告为一个决策,而 Embedded Coder® 则会将该转移转换为一个包含多个条件的复杂表达式,因此它还接收条件覆盖率和 MCDC 覆盖率:
else if ((CruiseControl_DW.CoastSetSw_prev != CruiseControl_DW.CoastSetSw_start) && CruiseControl_DW.CoastSetSw_start) {...}
解决代码覆盖率缺失问题
在此示例中,代码覆盖率分析未达到 100% 覆盖率,因为生成的代码产生了额外需要满足的覆盖率结果。要实现 100% 覆盖率,您可以:
添加新的测试用例,以覆盖当前测试用例未涉及的逻辑。您可以使用 Simulink® Design Verifier™ 生成测试用例以满足缺失的覆盖率。
如果一个或多个测试结果无法达到预期,或者测试用例需要过多的系统资源,请对覆盖率结果进行申述。
作为最佳作法,建议在分析代码覆盖率之前,先解决模型覆盖率缺失的问题。例如,如果模型覆盖率报告中存在决策覆盖缺失,则生成代码的代码覆盖率报告中也会存在相应的语句覆盖缺失。此外,您可以重用用于分析模型覆盖率的测试用例进行代码覆盖率分析,从而验证它们的行为等价性。
另请参阅
消除多余的局部变量(表达式折叠) (Simulink Coder)