How to test functions in a private directory?
-
12-10-2019 - |
Question
I'm using MATLAB xUnit to test some code. I'd like to be able to directly call some functions that are contained in a private
directory.
Here's a simple replicable setup:
Create yourself a project directory with two folders code
and test
. In code
, create a subdirectory named private
so you directory tree looks like
project_root
code
private
test
In the code
directory place a function
function y = main()
y = sub();
end
In the private
dir place a function
function y = sub()
y = 123;
end
In the test
dir place a function
function testsub()
assertElementsAlmostEqual(sub(), 123);
end
Now navigate to the test dir and call runtests
. You should see an error saying that sub
is undefined.
private
directories aren't allowed on the matlab path so that isn't an option. I could possibly put a function in the code
dir that retrieves handles to all the private functions but this seems hacky.
What is the best way to get access to test the private functions?
EDIT:
The idea of navigating to the private directory has a problem. In theory I could call, e.g.,
cd(privateDirectory);
suite = TestSuite.fromName(testDirectory);
suite.run
Unfortunately the testing framework navigates to the directory containing the tests as soon as you call run
.
Solution
One solution is to navigate to the private directory from within testsub
, get a function handle to the private function you want using STR2FUNC, then navigate back to do the testing using that function handle. You could even put these steps in a separate helper function for your unit testing, like so:
function privateFcn = get_private_fcn(privateDir,fcnName)
oldDir = cd(privateDir); %# Change to the private directory
privateFcn = str2func(fcnName); %# Get a function handle
cd(oldDir); %# Change back to the original directory
end
And you would use this function in testsub
as follows:
function testsub()
privateDir = '...\project_root\code\private'; %# The path to the private
%# directory
privateFcn = get_private_fcn(privateDir,'sub'); %# Call get_private_fcn
assertElementsAlmostEqual(privateFcn(), 123); %# Apply your test
end
This works, although the MATLAB Editor gives me an M-Lint warning for using the function CD: "MCC use of the CD function is problematic." I think it's safe for you to ignore this warning since 1) the function get_private_fcn
changes the current directory, then immediately changes it back after getting the function handle and 2) you're not dealing with a deployed application.
OTHER TIPS
While you cannot put a private directory on your search path, you CAN cd to the private directory itself.
Once there, MATLAB will see the functions, and it can use them. This is how I do that testing myself on private functions.
The point of private directories is to have functions that have very limited visibility, i.e. only to the functions in code
. Thus, there is no official way (at least that I know of) to make them visible.
The function that would retrieve the handles to whatever is in code/private
seems to me the cleanest way to go about it.
The alternative would be to place testsub
inside code
. This has the advantage that the test functions are always together with the code they're supposed to test, but you may feel this "pollutes" your code directory.