How to generate method parameters based on class parameters for Matlab unit tests - matlab

A program I am working on performs calculations that involve objects that can only have several possible sets of values. These parameter sets are read from a catalogue file.
As an example say the objects are representing cars and the catalogue contains a value set {id: (name, color, power, etc.)} for each model. There are however many of these catalogues.
I use Matlab's unittest package to test if the calculations fail for any of the property combinations listed in the catalogues. I want to use this package, because it provides a nice list of entries that failed. I already have a test that generates a cell array of all ids for a (hardcoded) catalogue file and uses it for parameterized tests.
For now I need to create a new class for each catalogue file. I would like to set the catalogue file name as a class parameter and the entries in it as method parameters (which are generated for all class parameters), but I cannot find a way to pass the current class parameter to the local method for creating the method parameter list.
How can I make this work?
In case it is important: I am using Matlab 2014a, 2015b or 2016a.

I have a couple thoughts.
Short answer is no this can't be done currently because the TestParameters are defined as Constant properties and so can't change across each ClassSetupParameter value.
However, to me creating a separate class for each catalogue doesn't seem like a bad idea. Where does that workflow fallover for you? If desired you can still share code across these files by using a test base class with your content and an abstract property for the catalogue file.
classdef CatalogueTest < matlab.unittest.TestCase
properties(Abstract)
Catalogue;
end
properties(Abstract, TestParameter)
catalogueValue
end
methods(Static)
function cellOfValues = getValuesFor(catalog)
% Takes a catalog and returns the values applicable to
% that catalog.
end
end
methods(Test)
function testSomething(testCase, catalogueValue)
% do stuff with the catalogue value
end
function testAnotherThing(testCase, catalogueValue)
% do more stuff with the catalogue value
end
end
end
classdef CarModel1Test < CatalogueTest
properties
% If the catalog is not needed elsewhere in the test then
% maybe the Catalogue abstract property is not needed and you
% only need the abstract TestParameter.
Catalogue = 'Model1';
end
properties(TestParameter)
% Note call a function that lives next to these tests
catalogueValue = CatalogueTest.getValuesFor('Model1');
end
end
Does that work for what you are trying to do?
When you say method parameters I assume you mean "TestParameters" as opposed to "MethodSetupParameters" correct? If I am reading your question right I am not sure this applies in your case, but I wanted to mention that you can get the data from your ClassSetupParameters/MethodSetupParameters into your test methods by creating another property on your class to hold the values in Test[Method|Class]Setup and then referencing those values inside your Test method.
Like so:
classdef TestMethodUsesSetupParamsTest < matlab.unittest.TestCase
properties(ClassSetupParameter)
classParam = {'data'};
end
properties
ThisClassParam
end
methods(TestClassSetup)
function storeClassSetupParam(testCase, classParam)
testCase.ThisClassParam = classParam;
end
end
methods(Test)
function testSomethingAgainstClassParam(testCase)
testCase.ThisClassParam
end
end
end
Of course, in this example you should just use a TestParameter, but there may be some cases where this might be useful. Not sure if its useful here or not.

Related

Use unit-testing framework in matlab to test data

I would like to test datasets with a variable number of values. Each value should be tested and I would like to have a standardized output that I can read in afterward again. My used framework is Matlab.
Example:
The use case would be a dataset which includes, e.g., 14 values that need to be testet. The comparison is already completely handled by my implementation. So I have 14 values, which I would like to compare against some tolerance or similar and get an output like
1..14
ok value1
ok value2
not ok value3
...
ok value14
Current solution:
I try to use the unit-testing framework and the according TAPPlugin that would produce exactly such an output (tap), one for every unit-test. My main problem is that the unit-testing framework does not take any input parameters. I already read about parametrization, but I do not know how this helps me. I could put the values as a list into the parameter, but how to I pass them there? Afaik the unit-test class does not allow additional parameters during initialization, so I cannot include this in the program the way I want.
I would like to avoid to need to format the TAP output on my own, because it is already there, but only for unit-test objects. Unfortunately, I cannot see how to implement this wisely.
How can I implement the output of a test anything protocol where I have a variable amount of comparisons (values) in Matlab?
If you are using class based unit tests you could access its properties from outside the test.
So let's say you have following unit test:
classdef MyTestCase < matlab.unittest.TestCase
properties
property1 = false;
end
methods(Test)
function test1(testCase)
verifyTrue(testCase,testCase.property1)
end
end
You could access and change properties from outside:
test=MyTestCase;
MyTestCase.property1 = true;
MyTestCase.run;
This should no succeed since you changed from false to true. If you want to have a more flexible way, you could have a list with the variables and a list with the requirements and then cycle through both in one of the test functions.
properties
variables = [];
requirements = [];
end
methods(Test)
function test1(testCase)
for i = 1:length(variables):
verifyEqual(testCase,testCase.variables[i],testCase.requirements [i])
end
end
end
Now you would set variables and requirements:
test=MyTestCase;
MyTestCase.variables = [1,2,3,4,5,6];
MyTestCase.requirements = [1,3,4,5,5,6];
MyTestCase.run;
Please note, that in theory you should not have multiple assert statements in one test.

Matlab: How to unit test a Questdlg box?

I have this chunk of code which display a question box with three choices:
Yes
Save as
No
I just want to create a unit test for each of those choices, and I need to interact with the box for it.
When the box is created, every matlab process is frozen until the user react. Of course my tests are automated, and there's no user present.
Is there a solution to send a "Yes" event to Matlab ?
I could use autoit but I would rather avoid that
Thanks
Currently, you're best bet is to structure your code to not depend on the questdlg function directly but to wrap an interface around the function so that you can inject a test specific dependency, or "mock". This might look something like the following:
Source Code Under Test
function codeWhichUsesQuestDlg(dlgProvider)
validateattributes(dlgProvider, {'DialogProvider'},{});
if (needToAskQuestion)
result = dlgProvider.provideQuestionDialog(...)
else
...
end
Source Code Interface/Infrastructure
classdef DialogProvider < handle
methods(Abstract)
result = provideQuestionDialog(varargin);
% perhaps others? errordlg, etc?
end
end
Production Implementation
classdef ProductionProvider < DialogProvider
methods
function result = provideQuestionDialog(varargin)
result = questdlg(varargin{:});
end
end
end
Production Usage
>> codeWhichUsesQuestDlg(ProductionProvider)
Test Usage
classdef TestCode < matlab.mock.TestCase
methods(Test)
function testCode(testCase)
% Create the test specific "mock" implementation
[mockProvider, behavior] = testCase.createMock(?DialogProvider);
% Define mock behavior needed for the test
when(withAnyInputs(behavior.provideQuestionDialog), ...
AssignOutputs('Yes'));
% Call code under test with the mock
codeWhichUsesQuestDlg(mockProvider);
% Verify correct result/behavior
...
end
end
end
Take a look at the mocking framework to see more info. Also you might be interested in this post covering the mocking framework as well as this post on dependency injection.

Matlab - object orientated with abstract Interface - How creating object?

Hello lovely community,
i am quite new here, but still hope someone can help me out. I just worked a bit with Matlab in the past and want to do a new project. Earlier I just stored all in one Matlab file and didn't had the need to use classes. This has changed now, so I hope someone can explain me what I did wrong.
My desire is to create the project object based. Therefore I started creating new folders in the main folder:
C:\Users\Luftfahrt\MAV\
The folder names are:
+Data
+Model
After I read the first chapters of
A guide to MATLAB orientaded programming
I figured out that with the plus symbol I am creating public objects. Exactly as I want. In each folder I inserted an abstract Interface and a child for it.
DataLoaderIF
classdef DataLoaderIF< handle
methods (Abstract=true)
Data = LoadData(Asset,Start,End)
Status = getStatus(Obj)
Info = getInfo(Obj)
end
end
When i run this code above he is telling me that Abstract classes cannot be instantiated, but I did it exactly as in the book. Maybe I thought, it is stupid run code from an abstract interface, so that there is no problem, is that true?
DataLoader
classdef DataLoader < DataManager.DataLoaderIF
%Inheritent from DataLoaderIF. Is setting parameter and Importing
properties (Access=protected)
mStatus =-1; %nothing done
mInfo ='Import'; %
mData; %saving the imported data
mCollector; %to save the prices after structuring
end
methods
%creating the constructor
function Obj = DataManager
function getStatus(Obj)
mStatus=1;
end
function getInfo(Obj)
Info='Import';
mInfo= Info;
end
function LoadData(Asset,Start,End)
connection = yahoo;
mData= fetch(connection, Asset, Start,End, 'd');
close(connection)
%'JPY=X', '01-Jun-2011', datestr(now,'dd-mmm-yyyy'), 'd');
mCollector= [{'date' 'open' 'high' 'low' 'close' 'volume' 'adj-close'}
cellstr(datestr(mData(:,1))) num2cell(mData(:,2:end))];
end
end
What I wanted to do now is to create an Object and then give this Object the variables to perform the fetch. But how can I instantiate now the Object? He says my constructor is false.
Someone has some ideas?
P.S. I already looked here Documentation Matlab, but this didn't help me out.
Thanks a lot!
It is not clear what you want to do exactly and why you need an abstract class then a derived one, but assuming you really need all that for more purpose than you described, take the following into account:
By definition in OOP, an abstract class cannot be instantiated. It is only a basic framework for the different classes which will inherit from it, and you can only instantiate these inheriting classes. abstract classes are only useful if the different inheriting classes represent different objects but need to share a set of (almost) common methods. If not, forget the 'abstract' parent and just design the class that does what you need.
Be careful with the classes which inherit from the handle class. In Matlab they behave differently than the value classes. Read this article and decide which type you want.
If you decide to use a handle class, consider the following very important factor Initialising property value:
Initializing Properties to Unique Values
MATLAB assigns properties to the specified default values only once
when MATLAB loads the class definition. Therefore, if you initialize a
property value with a handle-class constructor, MATLAB calls this
constructor only once and every instance references the same handle
object. If you want a property value to be initialized to a new
instance of a handle object each time you create an object, assign the
property value in the constructor.
Now with all that in mind, below is a version of your class that does run, and that you can instantiate as below:
>> dl = DataLoader
dl =
DataLoader with no properties.
>> dl.getInfo
ans =
Import
>> dl.getStatus
ans =
-1
>> dl.LoadData(1,2,3) %// etc ...
The class definition is as follow
classdef DataLoader < DataLoaderIF
properties (Access=protected)
mStatus %// nothing done
mInfo %//
mData %// saving the imported data
mCollector %// to save the prices after structuring
end
methods
%// Constructor (and initialise default value). For classes which
%// inherit from the "handle" class it is very important to
%// intialise your default values IN THE CONSTRUCTOR, and NOT in
%// the property definition.
function obj = DataLoader
obj.mStatus = -1 ;
obj.mInfo = 'Import' ;
obj.mData = [] ;
obj.mCollector = [] ;
end
function Status = getStatus(obj)
Status = obj.mStatus ;
end
function Info = getInfo(obj)
%// a "get" type of function should not assign value, only
%// return information about the object.
Info = obj.mInfo ;
end
%// the "obj" parameter has to be the first parameter of the
%// function in it's signature.
function LoadData(obj,Asset,Start,End)
%// Put function help here
%// I don't know what this part of the code is supposed to do
%// so I leave it as it is. Be aware that the fucntion "fetch"
%// will have to be accessible in your context or the function
%// will error
connection = 'yahoo' ;
obj.mData = fetch(connection, Asset, Start , End, 'd') ;
close(connection)
obj.mCollector= [{'date' 'open' 'high' 'low' 'close' 'volume' 'adj-close'}
cellstr(datestr(obj.mData(:,1))) num2cell(obj.mData(:,2:end))];
%// Here do your own test with your own conditions to decide
%// what the status of the object should be.
if ~isempty(obj.mData) && ~isempty(obj.mCollector)
obj.Status = 1 ;
end
end
end
end
You seemed a bit confused on some concept of OOP. If your first contact with OOP is through Matlab I totally understand where you come from. I had the same experience and my understanding of OOP was wrong for many years (my OOP code was very poor and inefficient too as a result), until I properly learned my way in C++ and .Net. These last two languages are real OOP languages (I know, not the only ones, or even better one, I don't want to start a debate), in the sense that you need to understand the OOP concepts to get anything out of them. On the other hand, you can spend your life doing wonderful things on Matlab and remain blissfully unaware of what even OOP means.
OOP capability was introduced in Matlab as a "convenience" for programmers who missed this way of structuring their code. The first implementations were very clunky and unpractical (raise your hand if you remember having to code each and every one of your subassign, subsref, display, get, set etc for each single object !!). It has been drastically improved since then, until it is now something worth the extra coding effort if you want to get the benefit of OOP organisation (code reuse, polymorphism, inheritance etc ...). However, to this day the OOP syntax in Matlab remain un-instinctive at first even for OOP veterans (why the hell do we have to declare the object itself as the first parameter of the function, is the compiler so blind it does't see the function is in the class definition?). You just have to get used to it first, then it gets ok.
The Matlab documentation on OOP is mostly oriented to these veterans. It explains to people who knows OOP on another languages how to apply the concepts in the Matlab specific syntax. It is not at all a very good guide for pure beginners.
This (longer than I wanted, sorry) blurb, was to try to explain that:
If you need to learn OOP concepts, train yourself with another language first. (seriously, even with the learning curve of learning another language, you'll loose less time than with the trial and error approach on Matlab).
If you do not have a definite identified need for OOP code in Matlab, do not insist. You can do a lot of things (in fact almost everything) in Matlab without resorting to classes (at least not knowingly, of course you will use the base Matlab classes in the background, but you can use and maintain your car for many years without necessarily having an intimate knowledge of its every component).

Matlab defining class functions in an elegant way for OOP

I am trying to implement a small example function in Matlab OOP.
The functioning code is:
classdef Cat < handle
properties
meowCount = 0;
end
methods
function obj = Cat() % all initializations, calls to base class, etc. here,
end
function Meow(obj)
disp('meowww');
obj.meowCount = obj.meowCount + 1;
end
end
end
I want to create something of the following sort akin to C++ as my real life function definitions are very big and I don't want to clutter my class definition:
classdef Cat < handle
properties
meowCount = 0;
end
methods
function obj = Cat() % all initializations, calls to base class, etc. here,
end
function Meow(obj);
end
end
%%
function Cat::Meow(obj)
disp('meowww');
obj.meowCount = obj.meowCount + 1;
end
So, basically write the definition of function Meow outside the class. How do I accomplish the above change ?
To play with the working first version you can use the following:
C = Cat;
C.meowCount
C.Meow
Create a folder called #Cat.
The within #Cat, put the following files:
Cat.m
classdef Cat < handle
properties
meowCount = 0;
end
methods
function obj = Cat()
end
Meow(obj) % this is optional, and just indicates the function signature
end
end
Meow.m
function Meow(obj)
disp('meowww');
obj.meowCount = obj.meowCount + 1;
end
Move out of the #Cat folder, and make sure it (or its parent folder) is on your path. Then try your examples.
If you use an # folder to contain your class like this, most methods (though not constructors, and not property get/set methods) can be moved to external files.
If you want, you can include a function signature with no implementation in the main classdef file. This is sometimes optional, but if you wish to change the Access level of the method away from default, it is necessary.
There are two ways of defining methods of a class. The newer, more portable way, is by defining them within the same classdef file. You can also write methods as separate M-file functions and put them in a #MyClass folder. Note that some methods must be in the classdef file. You can still define your separate file methods as static and private via helper functions. This is a bit of hack, which is why it's a good idea to put everything in the classdef file unless you have a very large project.
The best way to deal with clutter in your classdef file is to use code-folding. You can collapse individual methods and entire method blocks. In this way you can easily organize your classdef file to be as uncluttered as possible by grouping related methods together in the same methods block. Collapse any methods/blocks you aren't using at the time.
Additionally, you can use the "Go To" button in the Editor Ribbon Tab to select a specific method to view (if they are all defined in the same file).
Writing your methods in separate files may seem like a good solution at first, but if you have a class with many methods, it becomes extremely cumbersome to have many files open at once. Unlike C++, you can only define one method per file. It really ends up being quite a mess.
See Also:
Code Folding — Expand and Collapse Code Constructs
Editor/Debugger Code Folding Preferences

about matlab's Adaptfilt.<algorithm> function

Matlab's DSP toolbox has a function called adaptfilt., where calling adaptfilt is not enough, but you must add the .< algorithm> where the algorithm can be one of the many things, which we can view using help adaptfilt. What kind of Matlab structure has been used here (or what is the . operator and how can I make my own function that has to be called using a dot).
Also, the result of doing, say, adaptfilt.fdaf, gives a result that seems like a structure. How can I view all the elements of this structure (that is, if there are any more members besides the values that are returned on the screen by the function itself)?
adaptfilt is a class definition, of which fdaf is a member. Then, you use the dot operator to access the static member of the class. See Static Methods in the MATLAB documentation. In summary, to define a similar function yourself use
classdef MyClass
...
methods(Static)
function y = yourFunc(x)
...
end
end
end
The result you're getting from adaptfilt.fdaf is in fact an object. The adaptfilt.fdaf documentation page outlines the members of the object.