I have been tinkering lately with fully integrating continuous testing into my Matlab development cycle and have run across a problem I don't know how to get around. As almost all users know, Matlab kindly hides sub-functions within an M-file from the view of any functions outside that M-file. A toy example can be seen below:
function [things] = myfunc(data)
[stuff] = mysubfunc(data)
things = mean(stuff);
end
I want to perform unit testing on subfunc itself. This is, AFAIK, impossible because I cannot call it from any external function.
I'm currently using Matlab xUnit by Steve Eddins and cannot get around this issue. The easy solution -- splitting subfunc out to its own M-file -- is not acceptable in practice because I will have numerous small functions I want to test and don't want to pollute my filesystem with a separate M-file for each one. What can I do to write and perform easy unit tests without making new files for each function I want to test?
Arrange/Act/Assert (AAA) is a pattern for organizing unit tests. It breaks tests down into three clear and distinct steps: Arrange: Perform the setup and initialization required for the test. Act: Take action(s) required for the test. Assert: Verify the outcome(s) of the test.
Unit testing can be a reality check for your C# code. It makes sure that your C# code works perfectly fine and returns the expected results. In the above example, you can see that every time the test case runs it matches the expected value.
What you need to do in general is get function handles to your subfunctions from within the primary function and pass them outside the function where you can unit test them. One way to do this is to modify your primary function such that, given a particular set of input arguments (i.e. no inputs, some flag value for an argument, etc.), it will return the function handles you need.
For example, you can add a few lines of code to the beginning of your function so that it returns all of the subfunction handles when no input is specified:
function things = myfunc(data)
if nargin == 0 % If data is not specified...
things = {@mysubfunc @myothersubfunc}; % Return a cell array of
% function handles
return % Return from the function
end
% The normal processing for myfunc...
stuff = mysubfunc(data);
things = mean(stuff);
end
function mysubfunc
% One subfunction
end
function myothersubfunc
% Another subfunction
end
Or, if you prefer specifying an input flag (to avoid any confusion associated with accidentally calling the function with no inputs as Jonas mentions in his comment), you could return the subfunction handles when the input argument data
is a particular character string. For example, you could change the input checking logic in the above code to this:
if ischar(data) && strcmp(data, '-getSubHandles')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With