Simulink and the MATLAB Unit Testing Framework
Today, I am happy to welcome guest blogger Ajay Puvvala to talk about testing.
Some time ago, Ajay passed by my desk and offered to blog about the tight integration between Simulink Test and MATLAB Unit Testing Framework, which got introduced in R2016b.
My answer was: Yes, of course... but before, we need to introduce what the MATLAB Unit Testing Framework is, and how it can be used in a Simulink context.
This is what Ajay will be describing today.
The Goal
As an example, we will test if the output of the code generated for a simple model matches the results of a normal mode simulation. For that, we create a harness model, and using model referencing we simulate our simple model both in normal and in Software-in-the-Loop mode.
Script, Function or Class based
Depending on your preferences and needs, MATLAB Unit Testing offers three frameworks: Script-Based, Function-Based and Class-Based. The flexibility and set of features of those frameworks increase in that order.
For this post, we decided to go for function-based, since it offers everything we need, with the convenience of procedural programming.
Let's begin by the simplest possible test one could write:
What is in this test?
- The main function in our test uses functiontests to return an array of tests, which are the other local functions in this file taking a test handle as input.
- The function testEquivalence is our main test, it simulates the model in normal and SIL mode, and compares the results.
- We use addTeardown to do the cleanup once the test is completed. In this case, this means closing the model.
- We use verifyEqual from the MATLAB Unit Test qualification library to compare the results.
When ready, use the runtests function to run all the tests in exampleTest.m.
As you can see, our test failed. To make this story more interesting, I purposely configured the generated code to link against a math library where the implementation of sin is slightly different than the one used by Simulink in normal mode. In case you were not aware, there are various math libraries implementing trigonometric functions in different ways, giving slightly different results.
Diagnostics
The failure diagnostics show a table with numerical mismatches. But as they say, an image is worth a thousand words. So, how can we have better diagnostics? Luckily, qualification methods accept a user diagnostics for additional diagnosis. It could be a string or character array, function handle or matlab.unittest.diagnostics.Diagnostic object. Let’s create a diagnostic that can help us visualize these signal mismatches rather than looking at a bunch of numbers.
We add the following function to our test file exampleTest.m to launch SDI and display a comparison in case the test fails.
and we specify this function as additional argument to verifyEqual
This time, when the test finishes, SDI shows us how different the signals are:
Tolerances
As we all know, doing bit-to-bit comparison with floating-point signals is usually a bad idea. You typically end up being to sensitive to floating-point roundoff errors. Instead, you want to verify that the results are equivalent within a certain tolerance.
For that, we can pass additional arguments to verifyEqual to specify relative and absolute tolerances
This time, the test passes!
What's next?
As I mentioned previously, if you want to read more about testing in general, I recommend that you visit the Developer Zone blog, which is dedicated to this topic.
I also recommend that you go through the Testing Frameworks documentation to see all the different features available to customize and enhance the example we went through in this blog post.
Next week, we will look at how using Simulink Test’s Test Manager can simplify the testing of Simulink models. Stay tuned!
- Category:
- Analysis,
- Code Generation,
- Model-Based Design
Comments
To leave a comment, please click here to sign in to your MathWorks Account or create a new one.