Этот пример показывает, как использовать функции Simulink® Design Verifier™, чтобы регистрировать входные сигналы, создать модель тестовой обвязки, сгенерировать тесты для недостающего покрытия, объедините модели тестовой обвязки и выполните тесты.
Пример запускается путем журналирования входных сигналов к компоненту, который реализует контроллер в его родительской модели и модели тестовой обвязки создания для контроллера от этого записанные данные. Вы используете Simulink Design Verifier, чтобы найти новый тест, который достигает недостающего покрытия. Затем вы объединяете первую модель тестовой обвязки с моделью тестовой обвязки, сгенерированной после анализа Simulink Design Verifier. Наконец, вы получаете все тесты и выполняете контроллер с теми тестами в режиме симуляции и режиме (SIL) программного обеспечения In the Loop, и сравниваете результаты с помощью API CGV.
Этот пример требует допустимой лицензии Stateflow®. Чтобы продемонстрировать выполнение теста в режиме (SIL) программного обеспечения In the Loop, это также требует допустимого Simulink® Coder™ и лицензий Embedded Coder™.
if ~license('test','stateflow') return; end canUseSIL = license('test','Real-Time_Workshop') && ... license('test','RTW_Embedded_Coder');
Модель slvnvdemo_powerwindow
содержит контроллер окна со стеклоподъемником и модель объекта управления младшего разряда. slvnvdemo_powerwindow/power_window_control_system/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
и функции cvsim
, чтобы измерить покрытие модели, достигнутое для моделей контроллеров slvnvdemo_powerwindow_controller
с регистрируемыми сигналами, которые получены в модели тестовой обвязки.
Функция cvhtml
представляет отчет, который указывает, что 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). Можно использовать существующие данные о покрытии путем определения информационного канала покрытия в параметре файла данных Покрытия и установки Проигнорировать целей, удовлетворенных в существующем параметре данных о покрытии к on
в панели Генерации тестов параметров конфигурации Simulink Design Verifier.
Как вы видите в отчете, Simulink Design Verifier ограничивает генерацию тестов целями покрытия, которые не покрыты существующим файлом покрытия. Заметьте, что 8 целей покрытия в диаграмме Stateflow control
, как доказывают, невыполнимы. Это указывает на ненужную избыточную логику, которая не может быть протестирована.
cvsave('existingCovFromLoggedSignals',covDataFromLoggedSignals); opts = sldvoptions; opts.DisplayUnsatisfiableObjectives = 'off'; opts.IgnoreCovSatisfied = 'on'; opts.CoverageDataFile = 'existingCovFromLoggedSignals.cvt'; opts.ModelCoverageObjectives = 'MCDC'; opts.TestSuiteOptimization = 'LongTestcases'; opts.SaveHarnessModel = 'on'; opts.ModelReferenceHarness = 'on'; [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: [1x1 struct] TestCases: [1x2 struct]
Используйте функцию sldvruncgvtest
, чтобы выполнить модель slvnvdemo_powerwindow_controller
в режиме симуляции с тестами, полученными от модели тестовой обвязки.
runopts = sldvruntestopts('cgv'); disp(runopts); runopts.cgvConn = 'sim'; cgvSim = sldvruncgvtest('slvnvdemo_powerwindow_controller',... loggedSignalsMergedHarness,runopts);
testIdx: [] allowCopyModel: 0 cgvCompType: 'topmodel' cgvConn: 'sim' Starting execution: ComponentType: topmodel Connectivity: sim InputData: 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: cgv_runtest\slvnvdemo_powerwindow_controller\slvnvdemo_powerwindow_controller_cgv_input_tc_2.mat End CGV execution: status completed
Теперь используйте функцию sldvruncgvtest
, чтобы выполнить модель slvnvdemo_powerwindow_controller
в режиме SIL с теми же тестами.
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: cgv_runtest\slvnvdemo_powerwindow_controller\slvnvdemo_powerwindow_controller_cgv_input_tc_1_1.mat ### Starting build procedure for model: slvnvdemo_powerwindow_controller ### Successful completion of build procedure for model: slvnvdemo_powerwindow_controller ### Preparing to start SIL simulation ... ### Starting SIL simulation for component: slvnvdemo_powerwindow_controller ### Stopping SIL simulation for component: slvnvdemo_powerwindow_controller End CGV execution: status completed Starting execution: ComponentType: topmodel Connectivity: sil InputData: cgv_runtest\slvnvdemo_powerwindow_controller\slvnvdemo_powerwindow_controller_cgv_input_tc_2_1.mat ### Starting build procedure for model: slvnvdemo_powerwindow_controller ### Successful completion of build procedure for model: slvnvdemo_powerwindow_controller ### Preparing to start SIL simulation ... ### Starting SIL simulation for component: slvnvdemo_powerwindow_controller ### Stopping SIL simulation for component: slvnvdemo_powerwindow_controller End CGV execution: status completed
sldvruncgvtest
возвращает объект cgv.CGV
после запущения тестов. Используйте API CGV, чтобы сравнить результаты выполнения в симуляции и режимах 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'); close_system('slvnvdemo_powerwindow_controller');