Unit Test Generated Code with MATLAB Coder
This example shows how to test the output of generated code by using MATLAB® unit tests with MATLAB® Coder™.
To monitor for regressions in code functionality, you can write unit tests for your code. In MATLAB, you can create and run unit tests by using the MATLAB testing framework. To test MEX code and standalone code that you generate from MATLAB code, you can use the same unit tests that you use to test MATLAB code.
A MEX function includes instrumentation that helps you to detect issues before you generate production code. Running unit tests on a MEX function tests the instrumented code in MATLAB. Generated standalone code (static library or shared library) does not include the instrumentation and can include optimizations that are not present in the MEX code. To run unit tests on standalone code in a separate process outside of MATLAB, use software-in-the-loop (SIL) or processor-in-the-loop (PIL) execution. To use SIL or PIL execution, you must have Embedded Coder®.
This example shows how to:
Create MATLAB unit tests that call your MATLAB function. This example uses class-based unit tests.
Generate a MEX function from your MATLAB function.
Run the unit tests on the MEX function.
Run the unit tests on standalone code by using SIL.
Examine the Files
To access the files that this example uses, click Open Script.
addOne.m
The example performs unit tests on the MEX function generated from the MATLAB function addOne
. This function adds 1 to its input argument.
function y = addOne(x) % Copyright 2014 - 2016 The MathWorks, Inc. %#codegen y = x + 1; end
TestAddOne.m
The file TestAddOne.m
contains a class-based unit test with two tests.
reallyAddsOne
verifies that when the input is 1, the answer is 2.addsFraction
verifies that when the input is pi, the answer is pi + 1.
For more information about writing class based-unit tests, see Class-Based Unit Tests.
classdef TestAddOne < matlab.unittest.TestCase % Copyright 2014 - 2016 The MathWorks, Inc. methods ( Test ) function reallyAddsOne( testCase ) x = 1; y = addOne( x ); testCase.verifyEqual( y, 2 ); end function addsFraction( testCase ) x = pi; y = addOne( x ); testCase.verifyEqual( y, x+1 ); end end end
run_unit_tests.m
The file run_unit_tests.m
calls runtests
to run the tests in TestAddOne.m
.
% Run unit tests % Copyright 2014 - 2016 The MathWorks, Inc. runtests('TestAddOne')
Run Unit Tests on a MEX Function with the MATLAB Coder App
To open the MATLAB Coder app, on the MATLAB Toolstrip Apps tab, under Code Generation, click the MATLAB Coder app icon.
To prepare for code generation, advance through the app steps.
On the Select Source Files page, specify that the entry-point function is
addOne
.On the Define Input Types page, specify that the input argument
x
is a double scalar.On the Check for Run-Time Issues step, enter code that calls
addOne
with representative input. For example,addOne(2)
. Perform this step to make sure that you can generate code for your MATLAB function and that the generated code does not have run-time issues.
For more complicated MATLAB functions, you might want to provide a test file for the Define Input Types and Check for Run-Time Issues steps. This test file calls the MATLAB function with representative types. The app uses this file to determine the input types for you. The test file can be different from the test file that you use for unit testing.
To generate the MEX function, on the Generate Code page:
For Build type, specify
MEX
.Click Generate.
Run the unit tests on the generated MEX.
Click Verify Code.
In the field for the test file, specify
run_unit_tests
.Make sure that you set Run using to Generated code.
Click Run Generated Code.
The app displays the test output on the Test Output tab. The unit tests pass.
Run Unit Tests After Modifying MATLAB Code
Modify addOne
so that the constant 1 is single-precision. To edit addOne
, in the upper-left corner of the app, under Source Code, click addOne
.
To generate a MEX function for the modified function, click Generate.
To run the unit tests:
Click Verify Code.
Make sure that you set the test file to
run_unit_tests
and Run using to Generated codeClick Run Generated Code.
The unit tests fail.
reallyAddsOne
fails because the class of the output type is single, not double.addsFraction
fails because the output class and value do not match the expected class and value. The output type is single, not double. The value of the single-precision output, 4.1415930, is not the same as the value of the double-precision output, 4.141592653589793.
Run Unit Tests With Software-in-the-Loop Execution in the App (Requires Embedded Coder)
If you have Embedded Coder, you can run the units tests on generated standalone code (static library or shared library) by using software-in-the-loop (SIL) execution.
Generate a library for addOne
. For example, generate a static library.
On the Generate Code page:
For Build type, specify
Static Library
.Click Generate.
Run the unit tests on the generated code.
Click Verify Code.
In the field for the test file, specify
run_unit_tests
.Make sure that you set Run using to Generated code.
Click Run Generated Code.
To terminate the SIL execution, click Stop SIL Verification.
Note: To use the Enable C/C++ code coverage option, you must have a MATLAB® Test™ license.
Run Unit Tests on a MEX Function by Using the Command-Line Workflow
If you use the command-line workflow to generate code, you can run unit tests on a MEX function by using coder.runTest
with a test file that runs the unit tests.
Generate a MEX function for the function that you want to test. For this example, specify that the input argument is a double scalar by providing a sample input value.
codegen addOne -args {2}
Code generation successful.
Run the units tests on the MEX function. Specify that the test file is run_unit_tests
and that the function is addOne
. When coder.runTest
runs the test file, it replaces calls to addOne
with calls to addOne_mex
. The unit tests run on the MEX function instead of the original MATLAB function.
coder.runTest('run_unit_tests', 'addOne')
Run Unit Tests With Software-in-the-Loop Execution at the Command Line (Requires Embedded Coder)
If you have Embedded Coder, you can run the units tests on generated standalone code (static library or shared library) by using software-in-the-loop (SIL) execution.
Create a coder.EmbeddedCodeConfig
object for a static library.
cfg = coder.config('lib');
Configure the object for SIL.
cfg.VerificationMode = 'SIL';
Generate code for the MATLAB function and the SIL interface.
codegen -config cfg -args {2} addOne
Run a test file that runs the unit tests with the SIL interface.
coder.runTest('run_unit_tests', ['addOne_sil.', mexext])
Terminate the SIL execution.
Click clear addOne_sil.