主要内容

创建和执行测试用例

此示例说明如何使用 Simulink® Design Verifier™ 函数记录输入信号、创建框架模型、为缺失覆盖率生成测试用例、合并框架模型以及执行测试用例。

首先,此示例将输入信号记录到在其父模型中实现控制器的组件,然后根据记录的数据为控制器创建框架模型。您可以使用 Simulink Design Verifier 查找可实现缺失覆盖率的新测试用例。然后,将第一个框架模型与 Simulink Design Verifier 分析后生成的框架模型合并。最后,捕获所有测试用例并在仿真模式和软件在环 (SIL) 模式下使用这些测试用例执行控制器,并使用 CGV API 比较结果。

检查产品可用性

此示例需要有效的 Stateflow® 许可证。为了演示软件在环 (SIL) 模式下的测试执行,还需要有效的 Simulink® Coder™ 和 Embedded Coder™ 许可证。

if ~license('test','Stateflow')
    return;
end

canUseSIL = license('test','Real-Time_Workshop') && ...
    license('test','RTW_Embedded_Coder');

将输入信号记录到组件并创建框架模型

slvnvdemo_powerwindow 包含一个电动车窗控制器和一个低阶被控对象模型。组件 control 是一个 Model 模块,它引用模型 slvnvdemo_powerwindow_controller,该模型使用 Stateflow® 图实现控制器。

要使用在被控对象模型中仿真控制器的信号为控制器创建框架模型,首先要记录输入信号,然后使用该记录的数据调用框架生成。

open_system('slvnvdemo_powerwindow');
load_system('slvnvdemo_powerwindow_controller');

loggedSignalsPlant = ...
    sldvlogsignals('slvnvdemo_powerwindow/power_window_control_system/control');

harnessModelFilePath = ...
    sldvmakeharness('slvnvdemo_powerwindow_controller',loggedSignalsPlant);
[~,harnessModel] = fileparts(harnessModelFilePath);

使用记录的信号测量覆盖率

使用 cvtest (Simulink Coverage)cvsim (Simulink Coverage) 函数,通过在框架模型中捕获的记录信号来测量控制器模型 slvnvdemo_powerwindow_controller 的模型覆盖率。

cvhtml (Simulink Coverage) 函数生成报告,指示通过对从闭环模型中捕获的测试用例进行仿真,实现了 40% 的决策覆盖率、35% 的条件覆盖率和 10% 的 MCDC 覆盖率。

test = cvtest(harnessModel);
test.modelRefSettings.enable = 'On';
test.modelRefSettings.excludeTopModel = 1;

covDataFromLoggedSignals = cvsim(test);
cvhtml('Coverage with Logged Test Cases',covDataFromLoggedSignals);

查找缺失覆盖率的测试用例

在测试生成过程中使用现有覆盖率数据之前,必须将数据保存到覆盖率数据文件 (.cvt) 中。您可以使用现有覆盖率数据,方法是在覆盖率数据文件参数中指定覆盖率数据路径,并在 Simulink Design Verifier 配置参数的测试生成窗格中将忽略现有覆盖率数据中满足条件的目标参数设置为 on

正如您在报告中所看到的,Simulink Design Verifier 将测试生成限制为仅针对现有覆盖率文件中未覆盖的覆盖率目标生成测试用例。请注意,Stateflow 图 control 中的 8 个覆盖率目标被证明无法满足。这表示存在无法测试的不必要的冗余逻辑。

cvsave('existingCovFromLoggedSignals',covDataFromLoggedSignals);

opts = sldvoptions;
opts.IgnoreCovSatisfied = 'on';
opts.CoverageDataFile = 'existingCovFromLoggedSignals.cvt';
opts.ModelCoverageObjectives = 'MCDC';
opts.TestSuiteOptimization = 'LongTestcases';
opts.SaveHarnessModel = 'on';
opts.ModelReferenceHarness = 'on';
opts.MaxProcessTime = 500;

[status, fileNames] = sldvrun('slvnvdemo_powerwindow_controller',opts,true);
[~, newHarnessModel] = fileparts(fileNames.HarnessModel);
open_system(newHarnessModel);

从框架模型合并测试用例

现在使用 sldvmergeharness 将生成的测试用例与记录的测试用例合并。该命令将一系列测试框架模型作为参量。

sldvmergeharness(harnessModel, newHarnessModel);

记录框架模型的测试用例

为了使用在合并的框架模型中捕获的测试用例以编程方式执行模型 slvnvdemo_powerwindow_controller,需首先使用 sldvlogsignals 函数以所需的数据格式获得所有测试用例的输入值。

loggedSignalsMergedHarness = sldvlogsignals(harnessModel);
disp(loggedSignalsMergedHarness);
    LoggedTestUnitInfo: [1×1 struct]
             TestCases: [1×2 struct]

使用 CGV API 在仿真模式下执行模型

使用 sldvruncgvtest 函数通过从框架模型中捕获的测试用例在仿真模式下执行模型 slvnvdemo_powerwindow_controller

runopts = sldvruntestopts('cgv');
disp(runopts);

runopts.cgvConn = 'sim';
cgvSim = sldvruncgvtest('slvnvdemo_powerwindow_controller',...
    loggedSignalsMergedHarness,runopts);
     DefectChecker: 'off'
           testIdx: []
    allowCopyModel: 0
       cgvCompType: 'topmodel'
           cgvConn: 'sim'

Starting execution:
  ComponentType: topmodel
  Connectivity: sim
  InputData:
  /tmp/Bdoc25b_2988451_609737/tp1cf7cbb9/sldv-ex48508823/cgv_runtest/slvnvdemo_powerwindow_controller/slvnvdemo_powerwindow_controller_cgv_input_tc_1.mat
End CGV execution: status completed.
Starting execution:
  ComponentType: topmodel
  Connectivity: sim
  InputData:
  /tmp/Bdoc25b_2988451_609737/tp1cf7cbb9/sldv-ex48508823/cgv_runtest/slvnvdemo_powerwindow_controller/slvnvdemo_powerwindow_controller_cgv_input_tc_2.mat
End CGV execution: status completed.

使用 CGV API 在软件在环 (SIL) 模式下执行模型

现在使用 sldvruncgvtest 函数通过相同的测试用例在 SIL 模式下执行模型 slvnvdemo_powerwindow_controller

if canUseSIL
    runopts.cgvConn = 'sil';
else
    % When SIL is not possible, the example runs another simulation.
    runopts.cgvConn = 'sim';
end
cgvSil = sldvruncgvtest('slvnvdemo_powerwindow_controller',...
    loggedSignalsMergedHarness,runopts);
Starting execution:
  ComponentType: topmodel
  Connectivity: sil
  InputData:
  /tmp/Bdoc25b_2988451_609737/tp1cf7cbb9/sldv-ex48508823/cgv_runtest/slvnvdemo_powerwindow_controller/slvnvdemo_powerwindow_controller_cgv_input_tc_1_1.mat
### Searching for referenced models in model 'slvnvdemo_powerwindow_controller'.
### Total of 1 models to build.
### Starting build procedure for: slvnvdemo_powerwindow_controller
### Successful completion of build procedure for: slvnvdemo_powerwindow_controller

Build Summary

Top model targets:

Model                             Build Reason                                         Status                        Build Duration
===================================================================================================================================
slvnvdemo_powerwindow_controller  Information cache folder or artifacts were missing.  Code generated and compiled.  0h 0m 9.6928s 

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 10.028s
### Preparing to start SIL simulation ...
Building with 'gcc'.
MEX completed successfully.
### Starting SIL simulation for component: slvnvdemo_powerwindow_controller
### Application stopped
### Stopping SIL simulation for component: slvnvdemo_powerwindow_controller
End CGV execution: status completed.
Starting execution:
  ComponentType: topmodel
  Connectivity: sil
  InputData:
  /tmp/Bdoc25b_2988451_609737/tp1cf7cbb9/sldv-ex48508823/cgv_runtest/slvnvdemo_powerwindow_controller/slvnvdemo_powerwindow_controller_cgv_input_tc_2_1.mat
### Searching for referenced models in model 'slvnvdemo_powerwindow_controller'.
### Total of 1 models to build.
### Starting build procedure for: slvnvdemo_powerwindow_controller
### Successful completion of build procedure for: slvnvdemo_powerwindow_controller

Build Summary

Top model targets:

Model                             Build Reason                     Status                        Build Duration
===============================================================================================================
slvnvdemo_powerwindow_controller  Generated code was out of date.  Code generated and compiled.  0h 0m 5.661s  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 5.8487s
### Preparing to start SIL simulation ...
Building with 'gcc'.
MEX completed successfully.
### Starting SIL simulation for component: slvnvdemo_powerwindow_controller
### Application stopped
### Stopping SIL simulation for component: slvnvdemo_powerwindow_controller
End CGV execution: status completed.

比较仿真模式和 SIL 模式的结果

sldvruncgvtest 在运行测试后返回一个 cgv.CGV 对象。使用 CGV API 比较在框架模型中设计的每个测试用例在仿真模式和 SIL 模式下的执行结果,并表明它们是相等的。

for i=1:length(loggedSignalsMergedHarness.TestCases)
    simout = cgvSim.getOutputData(i);
    silout = cgvSil.getOutputData(i);

    [matchNames, ~, mismatchNames, ~ ] = ...
        cgv.CGV.compare(simout, silout);

    fprintf('\nTest Case(%d):  %d Signals match, %d Signals mismatch', ...
        i, length(matchNames), length(mismatchNames));
end
Test Case(1):  4 Signals match, 0 Signals mismatch
Test Case(2):  4 Signals match, 0 Signals mismatch

清理

要完成示例,请关闭所有模型。

close_system(harnessModel,0);
close_system(newHarnessModel,0);
close_system('slvnvdemo_powerwindow',0);
close_system('slvnvdemo_powerwindow_controller',0);