File Exchange Pick of the Week

Our best user submissions

I Think You’re Just Trying to Test Me!

Greg's pick this week is Unit Testing C Code using MATLAB and MATLAB Coder by Bill Chou.

In general I try to pick entries developed by those outside MathWorks, but Bill has provided a nice demonstration that combines two topics I'm passionate about: formalize testing and code generation.

Using unit testing in conjunction with MATLAB Coder enables three capabilities:

  • Automatically define interface data types for generated C-code.
  • Verify the C-code generated from MATLAB produces the expected results.
  • Execute tests developed in MATLAB against C-code developed outside the MATLAB environment.
  • I recommend taking a look at Bill's videos that go along with this entry.

    Contents

    What is unit testing and why would I use it?

    Fundamentally, a unit test determines if a single feature of software produces expected results under specific conditions. The theory is, by keeping the tests "small" and specific, it is easier to develop and maintain the software and tests.

    The primary benefit of having tests is it helps determine if a design meets its requirements. This could apply to the initial design of the software, or when you decide to make changes to the software.

    There are all sorts of additional philosophies and techniques that can apply unit testing such as Behavior Driven Development (BDD). I won't get into that here, sufficed to say that how you use unit tests will inform how you write them.

    Wait...There's unit testing in MATLAB?

    More specifically, there is a unit testing framework available in MATLAB. It is based on the xUnit framework. For those of you who might be stuck on older versions of MATLAB, it's worth checking out this File Exchange entry.

    The thing I like about using this the Unit Test framework in MATLAB is it provides a consistent means of defining tests, as well as a number of tools and functions to automate test execution. It also provides a number of levels of sophistication, so if you're not into writing classes and methods to exercise your code, you can use simple scripts or functions instead.

    For more about using this framework, I suggest checking out Andy's blog here.

    Why would I use MATLAB to run tests on my C-code?

    It seems unnecessary and possibly just using a tool because you can.

    Well use the right tool for the job. If you want your tests to leverage other MATLAB features that aren't readily available in the language you're using (plotting, filtering, data management), then it may very well make sense to develop your test suite in MATLAB.

    Side benefit that Bill doesn't mention

    In the videos I linked above, Bill does a nice job of going through how to apply the unit tests to the C-code testing process. However, there is an additional benefit for C-code generation from MATLAB that Bill doesn't address directly in the videos for this example.

    If you look at the second step of the MATLAB Coder app called "Define Input Types" you will notice that run_unit_tests appears in the dialog to "Automatically define input types".

    By executing the code found in this dialog, MATLAB Coder can determine what datatype is being used on the inputs to the function for which you are generating code, and apply the appropriate constraints.

    unittesttypedefinitionscript

    In this case you will see that the addOne function has an input variable x which is a scalar ( 1 x 1) of type double.

    unittesttypedefinitionresult

    An example of how to use this feature can be viewed at minute 2:30 of the video here.

    Type definition of the inputs is required because C-code is a statically typed language, while MATLAB is a dynamically typed language. (Check out this discussion for more detail about how these type systems differ)

    Modification to make test failures obvious.

    When the unit tests fail, you actually have to look at the test result summary to determine if there was a failure.

    To make it more prominent when there is a failure, I recommend throwing an error or assertion if there are any test failures. I changed run_unit_tests.m to the following:

      results = runtests( pwd );
      if any([results.Failed])
         error('Unit test failure');
      end

    unittesterrormessage

    That way, it becomes very obvious that there is an issue to be addressed.

    Any thoughts on this entry?

    Let us know here.




    Published with MATLAB® 9.0

    |

    Comments

    To leave a comment, please click here to sign in to your MathWorks Account or create a new one.