diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2f1a3c7..6a213d9 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,9 +1,11 @@
# This is a basic workflow to help you get started with MATLAB Actions
-name: CI
+name: MATLAB Build
# Controls when the action will run.
on:
- # Triggers the workflow on pull request events, but only for the main branch
+ # Triggers the workflow on push or pull request events, but only for the main branch
+ push:
+ branches: [ main ]
pull_request:
branches: [ main ]
@@ -11,7 +13,7 @@ on:
workflow_dispatch:
env:
- PRODUCT_LIST: MATLAB MATLAB_Test SimBiology Statistics_and_Machine_Learning_Toolbox
+ PRODUCT_LIST: MATLAB MATLAB_Test
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
@@ -22,15 +24,20 @@ permissions:
# Only allow one build of this type to run at a time
# Ensure results publishing completes without being interrupted/overwritten
concurrency:
- group: "test"
+ group: "test and publish results"
cancel-in-progress: false
jobs:
+ # This workflow contains a single job called "build"
+ build:
- test:
+ # Set up URLs for GitHub Pages report
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
# The type of runner that the job will run on
- runs-on: windows-latest
+ runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
@@ -50,3 +57,36 @@ jobs:
uses: matlab-actions/run-build@v2
with:
tasks: test
+
+ # Configure GitHub Pages to accept your artifact uploads
+ - name: Setup Pages
+ uses: actions/configure-pages@v5
+
+ # Upload testing and code coverage reports to your repository
+ - name: Upload pages
+ uses: actions/upload-pages-artifact@v4
+ with:
+ path: results # Upload results
+
+ # Publish reports to GitHub Pages so they can be viewed in a browser
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
+
+
+
+ # ==================================== #
+ # Alternate ways to run commands in CI #
+ # ==================================== #
+
+ ## Runs your tests using `runtests` command
+ #- name: Run all tests
+ # uses: matlab-actions/run-tests@v2
+ # with:
+ # source-folder: code
+
+ ## Executes custom MATLAB scripts, functions, or statements
+ #- name: Run custom testing procedure
+ # uses: matlab-actions/run-command@v2
+ # with:
+ # command: disp('Running my custom testing procedure!'); addpath('code'); results = runtests('IncludeSubfolders', true); assertSuccess(results);
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
deleted file mode 100644
index 623cdd1..0000000
--- a/.github/workflows/deploy.yml
+++ /dev/null
@@ -1,99 +0,0 @@
-# This is a basic workflow to help you get started with MATLAB Actions
-name: MATLAB Build
-
-# Controls when the action will run.
-on:
- # Triggers the workflow on push events, but only for the main branch
- push:
- branches: [ main ]
-
- # Allows you to run this workflow manually from the Actions tab
- workflow_dispatch:
-
-env:
- PRODUCT_LIST: MATLAB MATLAB_Test SimBiology Statistics_and_Machine_Learning_Toolbox
-
-# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
-permissions:
- contents: read
- pages: write
- id-token: write
-
-# Only allow one build of this type to run at a time
-# Ensure results publishing completes without being interrupted/overwritten
-concurrency:
- group: "test and publish results"
- cancel-in-progress: false
-
-jobs:
-
- build:
-
- # Set up URLs for GitHub Pages report
- environment:
- name: github-pages
- url: ${{ steps.deployment.outputs.page_url }}
-
- # The type of runner that the job will run on
- runs-on: windows-latest
-
- # Steps represent a sequence of tasks that will be executed as part of the job
- steps:
-
- # Check out your repository
- - uses: actions/checkout@v5
-
- # Set up MATLAB on a GitHub-hosted runner
- - name: Setup MATLAB
- uses: matlab-actions/setup-matlab@v2
- with:
- products: ${{ env.PRODUCT_LIST }}
- cache: true
-
- # Run the MATLAB build tool to build and test your code
- - name: Run buildtool
- uses: matlab-actions/run-build@v2
- with:
- tasks: test
-
- # Configure GitHub Pages to accept your artifact uploads
- - name: Setup Pages
- if: always()
- uses: actions/configure-pages@v5
-
- # Upload testing and code coverage reports to your repository
- - name: Upload pages
- if: always()
- uses: actions/upload-pages-artifact@v4
- with:
- path: results # Upload results
-
- # # Upload compiled CTF file to deploy Web App
- # - name: Upload CTF file
- # uses: actions/upload-pages-artifact@v4
- # with:
- # name: WebApp_CTF
- # path: WebAppArchive/*.ctf
-
- # Publish reports to GitHub Pages so they can be viewed in a browser
- - name: Deploy to GitHub Pages
- id: deployment
- if: always()
- uses: actions/deploy-pages@v4
-
-
- # ==================================== #
- # Alternate ways to run commands in CI #
- # ==================================== #
-
- ## Runs your tests using `runtests` command
- #- name: Run all tests
- # uses: matlab-actions/run-tests@v2
- # with:
- # source-folder: code
-
- ## Executes custom MATLAB scripts, functions, or statements
- #- name: Run custom testing procedure
- # uses: matlab-actions/run-command@v2
- # with:
- # command: disp('Running my custom testing procedure!'); addpath('code'); results = runtests('IncludeSubfolders', true); assertSuccess(results);
diff --git a/README.md b/README.md
index b14faec..dfd68bc 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,15 @@
-[](https://github.com/ChezJe/MATLAB-SimBiology-DevOps-Workflow-Example/actions/workflows/deploy.yml)
+[](https://github.com/ChezJe/MATLAB-SimBiology-DevOps-Workflow-Example/actions/workflows/ci.yml)
[](https://ChezJe.github.io/MATLAB-SimBiology-DevOps-Workflow-Example/tests/)
[](https://ChezJe.github.io/MATLAB-SimBiology-DevOps-Workflow-Example/coverage/)
-# MATLAB®/SimBiology® DevOps Workflow Example
+# Generating Tests for Your MATLAB® Code Workshop
This workshop provides hands-on experience using some of MATLAB's powerful software testing and automation features.
## About the workshop
This hands-on workshop will guide you through:
-* forking your own copy of the "MATLAB-SimBiology-DevOps-Workflow-Example" repository on GitHub
+* forking your own copy of the "Generating Tests for Your MATLAB Code Workshop" repository on GitHub
* generating tests using your command history and MATLAB Copilot
* automatically finding and running existing tests
* measuring and exploring code coverage metrics for your code
@@ -26,4 +26,6 @@ Step-by-step workshop instructions can be found in:
* [WorkshopGuide.m](WorkshopGuide.m)
+
+
Copyright 2025 The MathWorks, Inc.
diff --git a/buildfile.m b/buildfile.m
index 523d623..ba5686a 100644
--- a/buildfile.m
+++ b/buildfile.m
@@ -7,6 +7,7 @@
% CodeIssues task
plan("check") = CodeIssuesTask(Results=["results/codeissues.sarif"; ...
"results/codeissues.mat"]);
+
% Test task
tTask = TestTask("tests", ...
SourceFiles = "code", ...
@@ -33,7 +34,7 @@
plan("generateSimFun").Inputs = fullfile(proj.RootFolder,"code","*.sbproj");
plan("generateSimFun").Outputs = fullfile(proj.RootFolder,"code","*.mat");
plan("test").Inputs = fullfile(proj.RootFolder,"code","*");
-plan("compile").Inputs = fullfile(proj.RootFolder,"code",["*.mat","*.mlapp","*.m"]);
+plan("compile").Inputs = fullfile(proj.RootFolder,"code",["*.mat","*.mlapp","graystyle.m"]);
plan("compile").Outputs = fullfile(proj.RootFolder,"WebAppArchive");
% Set default task
@@ -61,9 +62,9 @@ function compileTask(~)
MATfilename = dir(fullfile(rootFolder,"code","*.mat"));
MATfilename = fullfile(rootFolder,"code",MATfilename.name);
- s = load(MATfilename,"dependenciesSimFun");
+ load(MATfilename,"dependenciesSimFun");
- appDependencies = [MATfilename; s.dependenciesSimFun; ...
+ appDependencies = [MATfilename; dependenciesSimFun; ...
codeFiles; imgFiles];
appfilename = fullfile(rootFolder,"code","TMDDApp.mlapp");
diff --git a/code/ConcTimecourseView.m b/code/ConcTimecourseView.m
index 2cbe5d4..a341078 100644
--- a/code/ConcTimecourseView.m
+++ b/code/ConcTimecourseView.m
@@ -2,6 +2,7 @@
properties ( Access = private )
Model
+ Axes
ConcColors = [0.30,0.75,0.93;...
0.86,0.55,0.41;...
@@ -9,11 +10,7 @@
FontName = "Helvetica";
end
- properties ( Hidden )
- % Leave these properties Hidden but public to enable access for any test generated
- % with Copilot during workshop
- Axes
-
+ properties ( SetAccess=private, GetAccess={?tTMDDApp} )
% line handles
lhDrug
lhReceptor
@@ -38,16 +35,13 @@
xlabel(ax, "Time (hours)", 'FontName',obj.FontName);
ylabel(ax, "Concentrations (nanomole/liter)",'FontName',obj.FontName);
- obj.lhDrug = plot(ax, NaN, NaN, '-','Linewidth',2,'Color',obj.ConcColors(1,:),'DisplayName','Drug');
+ obj.lhDrug = plot(ax, NaN, NaN, '-','Linewidth',2,'Color',obj.ConcColors(1,:));
hold(ax,'on');
- obj.lhReceptor = plot(ax, NaN, NaN, '-','Linewidth',2,'Color',obj.ConcColors(2,:),'DisplayName','Receptor');
- obj.lhComplex= plot(ax, NaN, NaN, '-','Linewidth',2,'Color',obj.ConcColors(3,:),'DisplayName','Complex');
+ obj.lhReceptor = plot(ax, NaN, NaN, '-','Linewidth',2,'Color',obj.ConcColors(2,:));
+ obj.lhComplex= plot(ax, NaN, NaN, '-','Linewidth',2,'Color',obj.ConcColors(3,:));
hold(ax,'off');
- lgd = legend(ax,'show','FontName',obj.FontName,'Color','none');
- lgd.Box = "off";
-
- ax.XLimitMethod = "padded";
- ax.YLimitMethod = "padded";
+ lh = legend(ax,{'Drug','Receptor','Complex'},'FontName',obj.FontName);
+ lh.Box = 'off';
% instantiate listener
dataListener = event.listener( model, 'DataChanged', ...
diff --git a/code/LampView.m b/code/LampView.m
index 736d3b4..c457ec1 100644
--- a/code/LampView.m
+++ b/code/LampView.m
@@ -9,9 +9,7 @@
LampColorFailure = [0.85, 0.33, 0.10] % color of lamp if RO not between thresholds after day 1
end
- properties ( Hidden )
- % Leave these properties Hidden but public to enable access for any test generated
- % with Copilot during workshop
+ properties ( SetAccess=private, GetAccess={?tTMDDApp} )
LampObj
end
diff --git a/code/NCAView.m b/code/NCAView.m
index c4f3d47..9f05d46 100644
--- a/code/NCAView.m
+++ b/code/NCAView.m
@@ -7,9 +7,7 @@
end
- properties ( Hidden )
- % Leave these properties Hidden but public to enable access for any test generated
- % with Copilot during workshop
+ properties ( SetAccess=private, GetAccess={?tTMDDApp} )
NCAtable
end
diff --git a/code/ROTimecourseView.m b/code/ROTimecourseView.m
index e8048c7..84d9e50 100644
--- a/code/ROTimecourseView.m
+++ b/code/ROTimecourseView.m
@@ -8,10 +8,7 @@
'FontWeight','bold','LabelVerticalAlignment','middle'}; % style for threshold lines
end
- properties ( Hidden, SetAccess=private)
- % Leave these properties Hidden but public to enable access for any test generated
- % with Copilot during workshop
-
+ properties ( GetAccess = {?tTMDDApp} )
% line handles
lhRO
end
@@ -42,12 +39,12 @@
ylabel(ax, "RO (%)",'FontName',obj.FontName);
obj.lhRO = plot(ax, NaN, NaN, 'Color', obj.ROColors,'Linewidth',2);
- % yline(ax,model.ThresholdValues(1), '--','efficacy','FontName',obj.FontName,obj.ThresholdStyle{:});
- % yline(ax,model.ThresholdValues(2), '--','safety','FontName',obj.FontName,obj.ThresholdStyle{:});
+ yline(ax,model.ThresholdValues(1), '--','efficacy','FontName',obj.FontName,obj.ThresholdStyle{:});
+ yline(ax,model.ThresholdValues(2), '--','safety','FontName',obj.FontName,obj.ThresholdStyle{:});
% set limits
- ax.XLimitMethod = "padded";
+ xlim(ax,'auto');
ylim(ax,[-5, 105]);
% instantiate listener
diff --git a/code/SimulationModel.m b/code/SimulationModel.m
index 498c127..d4b4811 100644
--- a/code/SimulationModel.m
+++ b/code/SimulationModel.m
@@ -1,6 +1,17 @@
classdef SimulationModel < handle
% Class to simulate the TMDD model
+ properties ( SetAccess = private )
+ DoseTable % daily dose to apply to simulate
+ SimFun % exported SimFunction
+
+ SimData
+ SimDataTable
+
+ ThresholdValues = [20, 80] % threshold values
+
+ end
+
properties
% original values for resetting
Amount0 (1,1) double
@@ -9,28 +20,10 @@
Kel0 (1,1) double
Kdeg0 (1,1) double
Interval0 (1,1) double
- end
-
- properties ( Dependent )
ROIsBetweenThresholds (1,1) logical
end
- properties ( Hidden )
- % Leave these properties Hidden but public to enable access for any test generated
- % with Copilot during workshop
-
- DoseTable % daily dose to apply to simulate
- SimFun % exported SimFunction
-
- SimDataTable
- SimData
-
- ThresholdValues = [20, 80] % threshold values
- end
-
- events ( NotifyAccess = public )
- % Leave this notification public to enable access for any test generated
- % with Copilot during workshop
+ events ( NotifyAccess = private )
DataChanged
end
@@ -80,6 +73,10 @@ function simulate(obj, parameters)
idxNotIncreasing = diff(t.Time)<=0; % remove duplicates
t(idxNotIncreasing,:) = [];
+ % logical value to check whether or not RO remains between thresholds after day 1
+ aboveThreshold1 = all(t.RO(t.Time >= 24) >= obj.ThresholdValues(1)/100);
+ belowThreshold2 = all(t.RO(t.Time >= 24) <= obj.ThresholdValues(2)/100);
+ obj.ROIsBetweenThresholds = aboveThreshold1 && belowThreshold2;
obj.SimData = sd;
obj.SimDataTable = t;
@@ -88,13 +85,6 @@ function simulate(obj, parameters)
end % simulate
- function value = get.ROIsBetweenThresholds(obj)
- % logical value to check whether or not RO remains between thresholds after day 1
- timeAfter24h = obj.SimDataTable.Time >= 24;
- ROAfter24h = obj.SimDataTable.RO(timeAfter24h);
- value = all(ROAfter24h >= obj.ThresholdValues(1)/100) && ...
- all(ROAfter24h <= obj.ThresholdValues(2)/100);
- end % get.ROIsBetweenThresholds()
end % public methods
diff --git a/code/TMDD.sbproj b/code/TMDD.sbproj
index 3480cba..be0de33 100644
Binary files a/code/TMDD.sbproj and b/code/TMDD.sbproj differ
diff --git a/code/TMDDApp.mlapp b/code/TMDDApp.mlapp
index 6c987c4..1a5add8 100644
Binary files a/code/TMDDApp.mlapp and b/code/TMDDApp.mlapp differ
diff --git a/code/simFunction_Dose.mat b/code/simFunction_Dose.mat
new file mode 100644
index 0000000..c9b533b
Binary files /dev/null and b/code/simFunction_Dose.mat differ
diff --git a/resources/project/Project.xml b/resources/project/Project.xml
index addadd3..e7171c4 100644
--- a/resources/project/Project.xml
+++ b/resources/project/Project.xml
@@ -152,67 +152,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -227,19 +166,8 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/tTMDDApp.m b/tests/tTMDDApp.m
index b0794e1..1957107 100644
--- a/tests/tTMDDApp.m
+++ b/tests/tTMDDApp.m
@@ -30,45 +30,44 @@ function testStartup(testCase)
end % testStartup
- % function testChangeDosingAmountAutomaticUpdate(testCase)
- %
- % % Deactivate automatic plot update
- % testCase.App.AutomaticupdateCheckBox.Value = false;
- %
- % % Simulate for drug=100
- % testCase.App.DosingAmountField.Value = 100;
- % testCase.App.updateApp();
- %
- % oldlhRO_XData = testCase.App.ROViewObj.lhRO.XData;
- % oldlhRO_YData = testCase.App.ROViewObj.lhRO.YData;
- % oldlhDrug_XData = testCase.App.ConcViewObj.lhDrug.XData;
- % oldlhDrug_YData = testCase.App.ConcViewObj.lhDrug.YData;
- % oldlhReceptor_XData = testCase.App.ConcViewObj.lhReceptor.XData;
- % oldlhReceptor_YData = testCase.App.ConcViewObj.lhReceptor.YData;
- % oldlhComplex_XData = testCase.App.ConcViewObj.lhComplex.XData;
- % oldlhComplex_YData = testCase.App.ConcViewObj.lhComplex.YData;
- %
- % % Activate automatic plot update
- % testCase.App.AutomaticupdateCheckBox.Value = true;
- %
- % % Drag slider
- % % testCase.drag(testCase.App.DosingAmountSlider,100,200); % requires display (does not work on github)
- % testCase.App.DosingAmountField.Value = 200; % BUT this does not trigger ValueChangedFcn callback ...
- %
- % % Check plot update
- % testCase.verifyNotEqual(oldlhRO_XData, testCase.App.ROViewObj.lhRO.XData, "x values for RO not updated");
- % testCase.verifyNotEqual(oldlhRO_YData, testCase.App.ROViewObj.lhRO.YData, "y values for RO not updated");
- % testCase.verifyNotEqual(oldlhDrug_XData, testCase.App.ConcViewObj.lhDrug.XData, "x values for Drug not updated");
- % testCase.verifyNotEqual(oldlhDrug_YData, testCase.App.ConcViewObj.lhDrug.YData, "y values for Drug not updated");
- % testCase.verifyNotEqual(oldlhReceptor_XData, testCase.App.ConcViewObj.lhReceptor.XData, "x values for Receptor not updated");
- % testCase.verifyNotEqual(oldlhReceptor_YData, testCase.App.ConcViewObj.lhReceptor.YData, "y values for Receptor not updated");
- % testCase.verifyNotEqual(oldlhComplex_XData, testCase.App.ConcViewObj.lhComplex.XData, "x values for Complex not updated");
- % testCase.verifyNotEqual(oldlhComplex_YData, testCase.App.ConcViewObj.lhComplex.YData, "y values for Complex not updated");
- %
- % % Check that lamp is set to false
- % testCase.verifyFalse(testCase.App.LampViewObj.IsOn);
- %
- % end % testChangeDosingAmountAutomaticUpdate
+ function testChangeDosingAmountAutomaticUpdate(testCase)
+
+ % Deactivate automatic plot update
+ testCase.App.AutomaticupdateCheckBox.Value = false;
+
+ % Simulate for drug=100
+ testCase.App.DosingAmountField.Value = 100;
+ testCase.App.updateApp();
+
+ oldlhRO_XData = testCase.App.ROViewObj.lhRO.XData;
+ oldlhRO_YData = testCase.App.ROViewObj.lhRO.YData;
+ oldlhDrug_XData = testCase.App.ConcViewObj.lhDrug.XData;
+ oldlhDrug_YData = testCase.App.ConcViewObj.lhDrug.YData;
+ oldlhReceptor_XData = testCase.App.ConcViewObj.lhReceptor.XData;
+ oldlhReceptor_YData = testCase.App.ConcViewObj.lhReceptor.YData;
+ oldlhComplex_XData = testCase.App.ConcViewObj.lhComplex.XData;
+ oldlhComplex_YData = testCase.App.ConcViewObj.lhComplex.YData;
+
+ % Activate automatic plot update
+ testCase.App.AutomaticupdateCheckBox.Value = true;
+
+ % Drag slider
+ testCase.drag(testCase.App.DosingAmountSlider,100,200);
+
+ % Check plot update
+ testCase.verifyNotEqual(oldlhRO_XData, testCase.App.ROViewObj.lhRO.XData, "x values for RO not updated");
+ testCase.verifyNotEqual(oldlhRO_YData, testCase.App.ROViewObj.lhRO.YData, "y values for RO not updated");
+ testCase.verifyNotEqual(oldlhDrug_XData, testCase.App.ConcViewObj.lhDrug.XData, "x values for Drug not updated");
+ testCase.verifyNotEqual(oldlhDrug_YData, testCase.App.ConcViewObj.lhDrug.YData, "y values for Drug not updated");
+ testCase.verifyNotEqual(oldlhReceptor_XData, testCase.App.ConcViewObj.lhReceptor.XData, "x values for Receptor not updated");
+ testCase.verifyNotEqual(oldlhReceptor_YData, testCase.App.ConcViewObj.lhReceptor.YData, "y values for Receptor not updated");
+ testCase.verifyNotEqual(oldlhComplex_XData, testCase.App.ConcViewObj.lhComplex.XData, "x values for Complex not updated");
+ testCase.verifyNotEqual(oldlhComplex_YData, testCase.App.ConcViewObj.lhComplex.YData, "y values for Complex not updated");
+
+ % Check that lamp is set to false
+ testCase.verifyFalse(testCase.App.LampViewObj.IsOn);
+
+ end % testChangeDosingAmountAutomaticUpdate
function testChangeDosingAmountManualUpdate(testCase)
@@ -85,22 +84,18 @@ function testChangeDosingAmountManualUpdate(testCase)
oldlhComplex_YData = testCase.App.ConcViewObj.lhComplex.YData;
% Drag slider
- if batchStartupOptionUsed()
- testCase.App.DosingAmountField.Value = 200;
- else
- testCase.drag(testCase.App.DosingAmountSlider,100,200); % requires display (does not work on github)
- end
+ testCase.drag(testCase.App.DosingAmountSlider,100,200);
% Check plot update
- testCase.verifyEqual(oldlhRO_XData, testCase.App.ROViewObj.lhRO.XData, "x values for RO were updated");
- testCase.verifyEqual(oldlhRO_YData, testCase.App.ROViewObj.lhRO.YData, "y values for RO were updated");
- testCase.verifyEqual(oldlhDrug_XData, testCase.App.ConcViewObj.lhDrug.XData, "x values for Drug were updated");
- testCase.verifyEqual(oldlhDrug_YData, testCase.App.ConcViewObj.lhDrug.YData, "y values for Drug were updated");
- testCase.verifyEqual(oldlhReceptor_XData, testCase.App.ConcViewObj.lhReceptor.XData, "x values for Receptor were updated");
- testCase.verifyEqual(oldlhReceptor_YData, testCase.App.ConcViewObj.lhReceptor.YData, "y values for Receptor were updated");
- testCase.verifyEqual(oldlhComplex_XData, testCase.App.ConcViewObj.lhComplex.XData, "x values for Complex were updated");
- testCase.verifyEqual(oldlhComplex_YData, testCase.App.ConcViewObj.lhComplex.YData, "y values for Complex were updated");
-
+ testCase.verifyEqual(oldlhRO_XData, testCase.App.ROViewObj.lhRO.XData, "x values for RO not updated");
+ testCase.verifyEqual(oldlhRO_YData, testCase.App.ROViewObj.lhRO.YData, "y values for RO not updated");
+ testCase.verifyEqual(oldlhDrug_XData, testCase.App.ConcViewObj.lhDrug.XData, "x values for Drug not updated");
+ testCase.verifyEqual(oldlhDrug_YData, testCase.App.ConcViewObj.lhDrug.YData, "y values for Drug not updated");
+ testCase.verifyEqual(oldlhReceptor_XData, testCase.App.ConcViewObj.lhReceptor.XData, "x values for Receptor not updated");
+ testCase.verifyEqual(oldlhReceptor_YData, testCase.App.ConcViewObj.lhReceptor.YData, "y values for Receptor not updated");
+ testCase.verifyEqual(oldlhComplex_XData, testCase.App.ConcViewObj.lhComplex.XData, "x values for Complex not updated");
+ testCase.verifyEqual(oldlhComplex_YData, testCase.App.ConcViewObj.lhComplex.YData, "y values for Complex not updated");
+
% Check that lamp is set to false
testCase.verifyTrue(testCase.App.LampViewObj.IsOn);