Main Content

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:

  1. Create MATLAB unit tests that call your MATLAB function. This example uses class-based unit tests.

  2. Generate a MEX function from your MATLAB function.

  3. Run the unit tests on the MEX function.

  4. Run the unit tests on standalone code by using SIL.

Examine the Files

The example performs unit tests on the MEX function generated from the MATLAB function addOne. This function adds 1 to its input argument.

type addOne.m
function y = addOne(x) %#codegen
y = x + 1;
end

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.

type TestAddOne.m
classdef TestAddOne < matlab.unittest.TestCase
    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

The file run_unit_tests.m calls runtests to run the tests in TestAddOne.m.

type run_unit_tests.m
runtests('TestAddOne')

Run Unit Tests by Using the MATLAB Coder App

Generate Code

To open the MATLAB Coder app, on the MATLAB Toolstrip Apps tab, under Code Generation, click the MATLAB Coder app icon.

Generate MEX code for the function addOne by following these steps:

  1. Open the Entry Points pane by clicking the Entry Points button in the MATLAB Coder toolstrip.

  2. Type or select addOne as an entry point function.

  3. Expand the function signature and specify that the input argument x is a double scalar.

  4. In the MATLAB Coder toolstrip, from the Build Type list, select MEX.

  5. In the MATLAB Coder toolstrip, click the Generate Code and Build button.

generate_and_build_mex.png

Run Unit Tests on MEX Function

To run units tests on the MEX function, click the Verify Using MEX button. Then, select the test file run_unit_tests.m.

verify_using_mex_succeed.png

The app displays the test output in the Command Window. The unit tests pass.

To confirm that the unit tests fail when MEX function returns incorrect output, change the generated code by modifying the type of input variable x. On the Entry Points pane, specify that the input argument x is a single scalar. Rerun the unit tests by clicking the Verify Using MEX button in the MATLAB Coder toolstrip.

verify_test_fail.png

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 Verification (Requires Embedded Coder)

If you have Embedded Coder®, you can run the unit tests on generated standalone code by using software-in-the-loop (SIL) verification.

First, generate a standalone static C library for addOne by following these steps:

  1. In the MATLAB Coder toolstrip, from the Build Type list, select Static Library (.lib).

  2. In the MATLAB Coder toolstrip, click the Verify Using SIL button. The app uses the test file run_unit_tests.m.

verify_using_sil.png

Run Unit Tests at the Command Line

Generate Code

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 addOne function. Specify that the input argument is a double scalar by providing a sample input value.

codegen addOne -args {2}
Code generation successful.

Run Unit Tests on MEX Function

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. The unit tests pass.

coder.runTest("run_unit_tests","addOne");
ans = 
  1×2 TestResult array with properties:

    Name
    Passed
    Failed
    Incomplete
    Duration
    Details

Totals:
   2 Passed, 0 Failed, 0 Incomplete.
   0.014247 seconds testing time.

To confirm that the unit tests fail when MEX function returns incorrect output, change the generated code by modifying the type of input variable x. Regenerate the MEX function, and specify that the input argument is a single scalar.

codegen addOne -args {single(2)}
Code generation successful.

Run unit tests on the modified MEX function. The unit tests fail.

coder.runTest("run_unit_tests","addOne")
ans = 
  1×2 TestResult array with properties:

    Name
    Passed
    Failed
    Incomplete
    Duration
    Details

Totals:
   0 Passed, 2 Failed (rerun), 2 Incomplete.
   0.0068377 seconds testing time.

Run Unit Tests with Software-in-the-Loop Verification (Requires Embedded Coder)

If you have Embedded Coder, you can run the unit tests on generated standalone code by using software-in-the-loop (SIL) verification.

Create a coder.EmbeddedCodeConfig object for a static library, and configure the object for SIL.

cfg = coder.config("lib");
cfg.VerificationMode = "SIL";

Generate code for the MATLAB function and the SIL interface. Specify that the input argument is a double scalar.

codegen -config cfg -args {2} addOne
Code generation successful.

Run a test file that runs the unit tests with the SIL interface. The unit tests pass.

coder.runTest("run_unit_tests",['addOne_sil.',mexext])
ans = 
  1×2 TestResult array with properties:

    Name
    Passed
    Failed
    Incomplete
    Duration
    Details

Totals:
   2 Passed, 0 Failed, 0 Incomplete.
   0.28996 seconds testing time.

clear addOne_sil
### Application stopped
### Stopping SIL execution for 'addOne'

See Also

Topics