%% Programmatically Create and Run Test Sequence Scenarios
%
% This example shows how to create and define multiple test scenarios in a single Test Sequence block. Being able to define more than one test sequence in a block lets you reduce the number of separate Test Sequence blocks in your test harness.
% This example uses the HeatPumpScenario1 model, which already has a test harness that contains a Test Sequence block.  In this example, you convert the block to use scenarios, add a new scenario to the block, edit a scenario step, and activate the new scenario so that it runs when the model simulates.
% This example also shows how to use scenarios in iterations to run multiple iterations in a single test case.
%% Open the Model and Test Harness
% Open the Controller subsystem of the HeatPumpScenario1 model and its test harness, ScenarioTest.

open_system('HeatPumpScenario1')
sltest.harness.open('HeatPumpScenario1/Controller','ScenarioTest');

%
%% Set Up the Scenarios
%% Enable Scenarios
% Set the Test Sequence block to use scenarios. The existing steps and transitions are moved into a scenario that, in this example, is named FirstScenario. Note that once you change a Test Sequence block to use scenarios, you cannot revert that block to non-scenario mode.

sltest.testsequence.useScenario('ScenarioTest/Test Sequence',...
   'FirstScenario');

%% Add Another Scenario
% Add a second scenario to the Test Sequence block. Name the scenario NewScenario.

sltest.testsequence.addScenario('ScenarioTest/Test Sequence','NewScenario');

%% Edit the Scenario Contents
% Edit the first step of the new scenario to change the values of the Troom_in and Tset variables. Preface the name of the step with the scenario name that contains the step. Similarly, when adding or changing transitions, you must also preface the transition with the scenario name.

action = sprintf('Troom_in = 75;\nTset = 75;\n');
sltest.testsequence.editStep('ScenarioTest/Test Sequence',...
    'NewScenario.step_1','Action',action);

% To view the scenario contents, use sltest.testsequence.findStep(blockPath), which returns an array containing the step names for all scenarios. Then, use sltest.testsequence.readStep(stepName)  or sltest.testsequence.readTransition(stepName) to see the contents of the specified step or transition, respectively. You can also view the scenario contents by double-clicking the Test Sequence block in the harness to open the block editor.
%% Specify Which Scenario to Run
% Specify the new scenario to run during model simulation. This scenario is the active scenario, which is the only scenario that runs during the simulation. For an alternative way to activate and run a scenario, or to run scenarios using iterations, see below.

sltest.testsequence.activateScenario('ScenarioTest/Test Sequence',...
   'NewScenario');

%% Run the Model
%% Run the Model Using the New Scenario
% You can run only one active scenario a time, unless you use a loop at the command line or in a script, or run iterations (see below). Note that fast restart is supported when switching active scenarios and running the model.

sim('ScenarioTest')

% In the test harness, view the Scope blocks to see the simulation results for the new scenario.
%% Run a Different Scenario
% Activate the first scenario.

sltest.testsequence.activateScenario('ScenarioTest/Test Sequence',...
   'FirstScenario');

% Rerun the model.

sim('ScenarioTest')

% In the test harness, view the Scope blocks to see the simulation results for the first scenario.
%% Use a Workspace Variable to Activate and Run a Scenario
% In some cases, such as for looping through scenarios, you might want to use a workspace variable to control which scenario to activate, instead of using activateScenario. The steps for using a workspace variable are:
% Set the scenario control source to the workspace by using sltest.testsequence.setScenarioControlSource('ScenarioTest/Test Sequence',sltest.testsequence.ScenarioControlSource.Workspace);
% Create a variable in the base workspace, model workspace, or data dictionary to specify the active scenario using its index value. For example, Active_Scenario_Index = 1;
% Run the model, which uses the steps and transitions in the active scenario.
% To run a different scenario, change the Active_Scenario_Index to the desired scenario, for example, Active_Scenario_Index = 2,  and then rerun the model.
% To change the name of the active scenario parameter from Active_Scenario_Index to, for example, ScenarioIndex, use  sltest.testsequence.editSymbol('ScenarioTest/Test Sequence',... 'Active_Scenario_Index','Name','ScenarioIndex');
% and then create the ScenarioIndex variable in the base workspace. Use Scenario_Index = 2 to set the variable to run the scenario identified by index 2, and then run the model.
%
%% Run Scenarios Using Iterations
% You can use iterations to run multiple scenarios in a single test case. The following steps use the same model, Test Sequence block, and scenarios defined above.
% 1. Set up the test file, test suite, and test case.

tf = sltest.testmanager.TestFile('Scenario Iterations Test');
ts = getTestSuites(tf);
tc = createTestCase(ts,'simulation','Sim Iterations');

% 2. Set the model and test harness for the test case.

setProperty(tc,'Model','HeatPumpScenario1');
setProperty(tc,'HarnessOwner','HeatPumpScenario1/Controller','HarnessName','ScenarioTest');

% 3. Get the names of the scenarios in the Test Sequence block.

tseq_block = 'ScenarioTest/Test Sequence'; 
scenarioNames = sltest.testsequence.getAllScenarios(tseq_block);

% 4. Set the Test Sequence block and default scenario for the test case.

setProperty(tc,'TestSequenceBlock',tseq_block);
setProperty(tc,'TestSequenceScenario','FirstScenario');

% 5. Use a loop to create the iterations, assign a scenario to each iteration, and add the iterations to the test case.

for i = 1:numel(scenarioNames)
   testItr = sltestiteration;
   setTestParam(testItr,'TestSequenceScenario',scenarioNames{i});
   addIteration(tc,testItr);
end

% 6. Run the test case.

run(tc);

%% Close the Test Harness and Model

sltest.harness.close('HeatPumpScenario1/Controller','ScenarioTest');
close_system('HeatPumpScenario1',0);

%
% Copyright 2020 The MathWorks, Inc.