Tim
Tim

Reputation: 1479

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

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.

Upvotes: 3

Views: 865

Answers (1)

Andy Campbell
Andy Campbell

Reputation: 2187

I have a couple thoughts.

  1. 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.

  2. 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?

  3. 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.

Upvotes: 1

Related Questions