Создание и выполнение тестов

Этот пример показывает, как использовать функции 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]

Выполните режим Model in Simulation с API CGV

Используйте функцию 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

Выполните режим Model in Software In the Loop (SIL) с API CGV

Теперь используйте функцию 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

Сравните результаты симуляции и режимов SIL

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');