Suppress figures in unit tests

6 views (last 30 days)
Gordon
Gordon on 2 Apr 2014
Commented: Wei Luo on 10 Apr 2019
Hi,
In the new unit testing framework, I am using the following code to try to temporarily suppress the plots generated by the functions being tested:
methods ( TestMethodSetup )
function killPlots ( testCase )
set(0,'DefaultFigureVisible','off');
end
end
methods ( TestMethodTeardown )
function loadPlots ( testCase )
set(0,'DefaultFigureVisible','on');
end
end
However, when I execute set(0,'DefaultFigureVisible','off'); inside the unit test, I cannot turn figures back on, even when I run the 'on' code inside the main session window.
Suppressing plots in unit tests works, but how do I turn them back on after execution?
Thanks,
Gordon

Accepted Answer

Andy Campbell
Andy Campbell on 2 Apr 2014
Hi Gordon,
This seems to work for me:
classdef KillFigureTest < matlab.unittest.TestCase
properties
OriginalDefault
end
methods ( TestMethodSetup )
function killPlots ( testCase )
set(0,'DefaultFigureVisible','off');
end
end
methods ( TestMethodTeardown )
function loadPlots ( ~ )
set(0,'DefaultFigureVisible','on');
end
end
methods(TestClassSetup)
function captureVisibility(testCase)
testCase.OriginalDefault = get(0,'DefaultFigureVisible');
end
end
methods(TestClassTeardown)
function checkVisibilityRestored(testCase)
testCase.assertEqual(get(0,'DefaultFigureVisible'), testCase.OriginalDefault);
end
end
methods(Test)
function createAFigure(testCase)
f = figure;
testCase.verifyEqual(get(f, 'Visible'), 'off');
end
end
end
When you interact with this this should fail when the visibility is not restored. See as follows:
>> get(0, 'DefaultFigureVisible')
ans =
on
>> run(KillFigureTest())
Running KillFigureTest
.
Done KillFigureTest
__________
ans =
TestResult with properties:
Name: 'KillFigureTest/createAFigure'
Passed: 1
Failed: 0
Incomplete: 0
Duration: 0.0504
Totals:
1 Passed, 0 Failed, 0 Incomplete.
0.050409 seconds testing time.
>> get(0, 'DefaultFigureVisible')
ans =
on
>>
However, there does seem to be something wrong in that you are assuming that the default was on to start the test. If the default was off, your TestMethodTeardown is clobbering the MATLAB session and not leaving MATLAB as you found it so to speak. Observe this in action:
>> set(0,'DefaultFigureVisible','off')
>> run(KillFigureTest())
Running KillFigureTest
.
================================================================================
Assertion failed while setting up or tearing down KillFigureTest.
As a result, all KillFigureTest tests failed and did not run to completion.
---------------------
Framework Diagnostic:
---------------------
assertEqual failed.
--> The strings are not equal
Actual String:
on
Expected String:
off
------------------
Stack Information:
------------------
In /KillFigureTest.m (KillFigureTest.checkVisibilityRestored) at 27
================================================================================
Done KillFigureTest
__________
Failure Summary:
Name Failed Incomplete Reason(s)
========================================================================
KillFigureTest/createAFigure X X Failed by assertion.
ans =
TestResult with properties:
Name: 'KillFigureTest/createAFigure'
Passed: 0
Failed: 1
Incomplete: 1
Duration: 0.0694
Totals:
0 Passed, 1 Failed, 1 Incomplete.
0.06943 seconds testing time.
>> get(0, 'DefaultFigureVisible')
ans =
on
>>
A better approach would be to capture the setting, turn it off as desired, and then restore it to whatever setting it was before. To show this I am using addTeardown . You don't have to do this, but I like how it streamlines the code, does not require a property on the class, and is deterministic with respect to teardown order. I also removed the checking code in TestClassSetup/Teardown because it seems to be working normally:
classdef KillFigureTest < matlab.unittest.TestCase
methods ( TestMethodSetup )
function killPlots ( testCase )
origDefault = get(0,'DefaultFigureVisible');
set(0,'DefaultFigureVisible','off');
testCase.addTeardown(@set, 0, 'DefaultFigureVisible', origDefault);
end
end
methods(Test)
function createAFigure(testCase)
f = figure;
testCase.verifyEqual(get(f, 'Visible'), 'off');
end
end
end
Observe how this now both keeps the visibility off in the context of the test but also respects what the setting was at start and restores it correctly.
>> set(0,'DefaultFigureVisible','off')
>> run(KillFigureTest());
Running KillFigureTest
.
Done KillFigureTest
__________
>> get(0, 'DefaultFigureVisible')
ans =
off
>> set(0,'DefaultFigureVisible','on')
>> run(KillFigureTest());
Running KillFigureTest
.
Done KillFigureTest
__________
>> get(0, 'DefaultFigureVisible')
ans =
on
>>
I hope that helps!
  1 Comment
Wei Luo
Wei Luo on 10 Apr 2019
Thanks man, it helps me a lot!
I am doing batch data processing and plotting everyday, and it is super anoying that the plots are keeping popping and I am not able to doing anyting else. Thanks again... it makes life more efficient.

Sign in to comment.

More Answers (1)

Gordon
Gordon on 2 Apr 2014
Thank you for the extended response!
Firstly, yes I believe it was working originally - so it was a user error (the problem was that I was used to being able to call plot() without calling figure first).
Secondly, your approach of using addTeardown is much better, so thank you for that as well!
Much appreciative.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!