Unit Test Generated Standalone Class
R2026bThis example shows how to use MATLAB® unit tests to validate an entry-point class. When you write MATLAB code, you can create and run unit tests by using the MATLAB testing framework. You can use the same unit tests to test the generated MEX code. If you have an Embedded Coder® license, you can also use MATLAB unit tests in software-in-the-loop (SIL) or processor-in-the-loop execution to verify the standalone class in a separate process outside of MATLAB. See Code Verification Through Software-in-the-Loop and Processor-in-the-Loop Execution (Embedded Coder).
Note
Using a MATLAB class as an entry point for code generation is a tech preview. This
feature is in active development and might change between the tech preview and the
general release. To enable the feature, enter
enableCodegenForEntryPointClasses at the command line before
launching the MATLAB
Coder™ app, calling the codegen function, or creating a coder.Type object. To provide feedback, email the
development team or participate
in a survey.
Unit Test Generated C++ Class with SIL Execution
In this example, you generate MEX code for an entry-point class and use a unit test to test the generated class. You then use verify the standalone C++ class in a separate process outside of MATLAB by using SIL.
Enable Tech Preview
Before you begin, enable code generation for entry-point classes.
enableCodegenForEntryPointClasses
=== Code generation for entry-point classes is ENABLED === To use the Classes As Entry-Points feature, restart MATLAB and rerun 'enableCodegenForEntryPointClasses' before calling codegen or coder.Type. For feature overview and example usage, see Code Generation for Entry-Point Classes. To send feedback or questions directly to the development team, email entrypointclassfeedback@groups.mathworks.com or click here to take survey.
Examine MATLAB Unit Tests
The example performs unit tests on the standalone C++ classes generated for simple and damped oscillators in the example Generate Standalone C++ Classes to Represent a Physical System.
Examine the MATLAB unit test, which instantiates and evolves each oscillator given the initial conditions described in the example. It then checks that the final position of each oscillator matches the expected value.
type tOscillators.mclassdef tOscillators < matlab.unittest.TestCase
methods (Test)
function matchesActualFinalPosition_simple(testCase)
obj = mySystem.simpleOscillator(1,1);
[~,x] = obj.evolution(1,0,100,0.1);
testCase.verifyEqual(x(end),0.8623,"AbsTol",5e-4);
end
function matchesActualFinalPosition_damped(testCase)
obj = mySystem.dampedOscillator(1,0.1,1);
[~,x] = obj.evolution(1,0,100,0.1);
testCase.verifyEqual(x(end),0.0056,"AbsTol",5e-4);
end
end
end
Run the unit tests on the MATLAB code. The tests pass.
runtests("tOscillators")Running tOscillators .. Done tOscillators __________
ans =
1×2 TestResult array with properties:
Name
Passed
Failed
Incomplete
Duration
Details
Totals:
2 Passed, 0 Failed, 0 Incomplete.
0.27371 seconds testing time.
Specify Entry-Point Classes
Create coder.ClassSignature objects for the simple and damped oscillator classes. Use the addMethod object function to specify the public methods that you want to access from your external C++ application. For this example, specify the constructor methods and the evolution methods.
classSig_simple = coder.ClassSignature("mySystem.simpleOscillator"); addMethod(classSig_simple,"simpleOscillator",{0,0}); addMethod(classSig_simple,"evolution",{classSig_simple,0,0,0,0})
ans =
coder.ClassSignature
1×1 mySystem.simpleOscillator
TypeName: "simpleOscillator"
Properties: struct with no fields.
Methods:
simpleOscillator:
Args: {1×1 double, 1×1 double}
evolution:
Args: {1×1 this, 1×1 double, 1×1 double, 1×1 double, 1×1 double}
classSig_damped = coder.ClassSignature("mySystem.dampedOscillator"); addMethod(classSig_damped,"dampedOscillator",{0,0,0}); addMethod(classSig_damped,"evolution",{classSig_damped,0,0,0,0})
ans =
coder.ClassSignature
1×1 mySystem.dampedOscillator
TypeName: "dampedOscillator"
Properties: struct with no fields.
Methods:
dampedOscillator:
Args: {1×1 double, 1×1 double, 1×1 double}
evolution:
Args: {1×1 this, 1×1 double, 1×1 double, 1×1 double, 1×1 double}
Run Unit Tests on MEX Code
Generate MEX code from the entry-point classes and use the test script to test the MEX classes. Because the function coder.runTest does not support entry-point classes, manually modify the test script to call the MEX function.
By default, calling the codegen command for multiple entry-point classes generates a C MEX function with the same name as the first MATLAB class passed to the command. For this example, specify a different name for the generated MEX function by using the -o option. Use the -class option to specify each class object, and use the -lang:c++ option to generate C++ code.
codegen -lang:c++ -o oscillatorsMex -class classSig_simple -class classSig_damped
Code generation successful.
Modify the test script to use the MEX classes. To invoke the class constructor for each class, pass the name of the class constructor to the MEX function, followed by the required inputs. Because the classes are inside a namespace, call the constructor methods by using dot notation. For this example, create the class instances by using these lines of code:
obj = oscillatorsMex("mySystem.simpleOscillator",1,1); obj = oscillatorsMex("mySystem.dampedOscillator",1,0.1,1);
The file tOscillatorsMex.m contains the updated code.
type tOscillatorsMex.mclassdef tOscillatorsMex < matlab.unittest.TestCase
methods (Test)
function matchesActualFinalPosition_simple(testCase)
obj = oscillatorsMex("mySystem.simpleOscillator",1,1);
[~,x] = obj.evolution(1,0,100,0.1);
testCase.verifyEqual(x(end),0.8623,"AbsTol",5e-4);
end
function matchesActualFinalPosition_damped(testCase)
obj = oscillatorsMex("mySystem.dampedOscillator",1,0.1,1);
[~,x] = obj.evolution(1,0,100,0.1);
testCase.verifyEqual(x(end),0.0056,"AbsTol",5e-4);
end
end
end
Run the unit tests on the MEX classes. The tests pass.
runtests("tOscillatorsMex.m")Running tOscillatorsMex .. Done tOscillatorsMex __________
ans =
1×2 TestResult array with properties:
Name
Passed
Failed
Incomplete
Duration
Details
Totals:
2 Passed, 0 Failed, 0 Incomplete.
0.063422 seconds testing time.
Run Unit Tests with SIL Verification
Next, if you have an Embedded Coder license, run the unit tests on the generated standalone code by using SIL verification. Because the function coder.runTest does not support entry-point classes, manually modify the test script to call the SIL function.
Create a code configuration object for a static library. To generate code for SIL verification, set the VerificationMode property to "SIL". See Verification mode.
cfg = coder.config("lib"); cfg.VerificationMode = "SIL";
Generate a SIL function by using the codegen command. Specify the configuration object by using the -config option and specify a different name for the generated SIL function by using the -o option. Use the -lang:c++ option to generate C++ code and the -class option to specify each class object.
codegen -config cfg -lang:c++ -o oscillatorsSIL -class classSig_simple -class classSig_damped
Code generation successful.
Modify the test script to use SIL verification. To invoke the class constructor for each class, pass the name of the class constructor to the SIL function, followed by the required inputs. Because the classes are inside a namespace, call the constructor methods by using dot notation. For this example, create the class instances by using these lines of code:
obj = oscillatorsSIL_sil("mySystem.simpleOscillator",1,1); obj = oscillatorsSIL_sil("mySystem.dampedOscillator",1,0.1,1);
The file tOscillatorsSIL.m contains the updated code.
type tOscillatorsSIL.mclassdef tOscillatorsSIL < matlab.unittest.TestCase
methods (Test)
function matchesActualFinalPosition_simple(testCase)
obj = oscillatorsSIL_sil("mySystem.simpleOscillator",1,1);
[~,x] = obj.evolution(1,0,100,0.1);
testCase.verifyEqual(x(end),0.8623,"AbsTol",5e-4);
end
function matchesActualFinalPosition_damped(testCase)
obj = oscillatorsSIL_sil("mySystem.dampedOscillator",1,0.1,1);
[~,x] = obj.evolution(1,0,100,0.1);
testCase.verifyEqual(x(end),0.0056,"AbsTol",5e-4);
end
end
end
Run the unit tests on the standalone C++ classes by using SIL. The tests pass.
runtests("tOscillatorsSIL.m")Running tOscillatorsSIL
### Starting SIL execution for 'oscillatorsSIL'
To terminate execution: clear oscillatorsSIL_sil
..
Done tOscillatorsSIL
__________
ans =
1×2 TestResult array with properties:
Name
Passed
Failed
Incomplete
Duration
Details
Totals:
2 Passed, 0 Failed, 0 Incomplete.
0.28266 seconds testing time.
Terminate SIL execution.
clear oscillatorsSIL_sil### Application stopped ### Stopping SIL execution for 'oscillatorsSIL'
See Also
addMethod | codegen | coder.ClassSignature | runtests