创建和执行测试用例
此示例说明如何使用 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);