While testing objects and functions of a project in Matlab using matlab.unittest.TestCase classes (new to 2013a), sometimes a plot is needed to visualise the actual/expected data.
I have so far used the following method but feel this isn't the best way:
classdef test1 < matlab.unittest.TestCase
properties
var1=3; var2=5; % sample variables
graph_output = 0; % boolean
end
methods(Test)
function testfunction(testCase)
my_result = my_fun(testCase.var1, testCase.var2);
testCase.verifyEqual(my_result,expected_result)
if testCase.graph_output
plot(my_result)
end
end
end
In the command line, I use test_obj=test1
and then test_obj.graph_output=1
before using run(test_obj)
to output graphs as well as testing the function.
A better way to do this would be to use a separate method. I have tried this by allocating my_result
to the properties list, but after the test completes, matlab seems to re-initialise my_result
making the output graph meaningless.
Does anyone know a way round this, or any better way of outputting test results on demand?
Usually when people are interested in looking at results from a specific test it's because something has gone wrong. This is a good opportunity to use custom diagnostics. Here is one that prints out a link to the MATLAB command window which plots the expected value against the actual value, as well as printing out links which will load the data from the test into the workspace.
classdef test1 < matlab.unittest.TestCase
methods(Test)
function firstTest(testCase)
import matlab.unittest.constraints.IsEqualTo;
% Test should pass!
actualValue = 1:10;
expectedValue = 1:10;
diagnostic = @()myPlotDiagnostic(actualValue, expectedValue);
testCase.verifyThat(actualValue, IsEqualTo(expectedValue), diagnostic);
end
function secondTest(testCase)
import matlab.unittest.constraints.IsEqualTo;
% Test should fail with a diagnostic!
actualValue = [1 2 3 4 12 6 7 8 9 10];
expectedValue = 1:10;
diagnostic = @()myPlotDiagnostic(actualValue, expectedValue);
testCase.verifyThat(actualValue, IsEqualTo(expectedValue), diagnostic);
end
function thirdTest(testCase)
import matlab.unittest.constraints.IsEqualTo;
% Test should also fail with a diagnostic!
actualValue = [1 2 3 4 -12 6 7 8 9 10];
expectedValue = 1:10;
diagnostic = @()myPlotDiagnostic(actualValue, expectedValue);
testCase.verifyThat(actualValue, IsEqualTo(expectedValue), diagnostic);
end
end
end
function myPlotDiagnostic(actualValue, expectedValue)
temporaryFile = tempname;
save(temporaryFile, 'actualValue', 'expectedValue');
fprintf('<a href="matlab:plot([%s], [%s], ''*r'')">Plot Data</a>\n', num2str(expectedValue), num2str(actualValue));
fprintf('<a href="matlab:load(''%s'')">Load data into workspace</a>\n', temporaryFile);
end
Running this test will result in outputs which contain
These will of course only show up though if the test fails, but this is generally the desired behaviour anyway!
N.B. I prefer to use the IsEqualTo
syntax so that the tests read (almost) like English. But this is a style decision.