Taking the Hassle Out of Testing
This cartoon sums up my feelings about testing.
Testing is great. When you have working tests, you feel clean and warm. The sun shines a little brighter and the birds sing a song just for you. But jeez, getting those tests up and working is such a pain. Writing tests is a nuisance, and running tests consistently (and capturing the results) is tedious. If only we could decrease that hassle while retaining the value, what a world it would be!
Hold that thought, my friends, because I want to show you something glorious. A bright new world where the birds sing a song just for you. If you have MATLAB code in a GitHub repo (and if you don't, I'll wait five minutes for you to put some there), then it's almost trivial to set up automated MATLAB testing. No fiddling with licenses and installs. It just works, and I can practically guarantee that it's easier than you think it is.
For this, I'll be showing you the tests I set up for my Animator repo on GitHub (and linked to from the File Exchange). Animator makes it easy to create little animations like the one shown here. In case you're wondering, you're looking at the three types of trochoid curves here: the cycloid, the curtate trochoid, and the prolate trochoid. But that's not what I came here to talk about.
The Animator tool builds animations by reaching into the Editor and manipulating the script that makes the image. So I have some finicky file parsing code that I'd like to protect with some tests.
There are some very fancy ways to set up tests, but I'm going to tell you the absolute easiest rock-bottom way to get started. Let's imagine you have a function called times2.m. It multiplies the input by 2. Here it is.
function y = times2(x) % Return the input multiplied by two. y = 2*x; end
Nice, eh? Let's say that's your whole toolbox, right there. Make a script called testTimes2.m and put this code in it.
testTimes2.m --------- %% Test 1 assert(isequal(times2(3),6)) %% Test 2 assert(isequal(times2(6),12))
The assert command is a good friend to have. You just give it an expression, and if it evaluates as true, it's completely silent. But if it's false, it throws an error and fails the test.
Now you go to your GitHub repo and create a new Actions workflow. You'll see a number of suggested items, but choose the option at the top of the page: "Set up a workflow yourself."
This will open up a web editor for the file main.yml. Stick the following text in there.
name: Run Tests on GitHub-Hosted Runner on: [push] jobs: my-job: name: Run MATLAB Tests and Generate Artifacts runs-on: ubuntu-latest steps: - name: Check out repository uses: actions/checkout@v3 - name: Set up MATLAB uses: matlab-actions/setup-matlab@v1 - name: Run tests and generate artifacts uses: matlab-actions/run-tests@v1
You can learn more about this code from the documentation on the matlab-actions repo. The bottom line is that the Continuous Integration team at MathWorks created some actions that automatically setup and run MATLAB tests. The code shown above is generic. You don't need to edit it. It will look around for any files that either begin or end with the magic sentinel string "test" (case insensitive). My Animator repo has a file called smokeTest.m that matches this criterion. I also have some MATLAB unit tests (in animatorTests.m), which you don't need to worry about for now. But those are automatically detected as well.
If we return to our imaginary times2 repo, once you save main.yml, every time you push any file to the repo, testTimes2.m will run, and those two assertions will make sure times2 is doing the right thing. And you'll always be testing on the latest version of MATLAB on the latest version of Ubuntu. Niiice.
One last thing. If you've turned on testing, you should tell the world. You can do that with a badge in your repo's README.md. Once again, it could hardly be easier. Stick this text at the top of your README. Naturally, you'll need to substitute the name and address of your own repo.
[![Animator CI/CD](https://github.com/gulley/Animator/actions/workflows/main.yml/badge.svg)] (https://github.com/gulley/Animator/actions/workflows/main.yml)
With zero configuration, this text will not only let your visitors know that you have tests. It will tell them whether the most recent test passed or failed.
That's all there is to it!
1. Make a simple test.
2. Create an action workflow with the text provided above
3. OPTIONAL. Add a badge for your README with the text provided above.
There are, of course, lots more bells and whistles to this process. As I said, you're getting the bargain basement version of testing. Once you get it working, you'll probably develop a taste for more sophisticated testing: MATLAB unit tests, project-defined testing files, filters that will only test certain kinds of changes. But that can wait.
For now, just enjoy that clean, warm feeling.
To leave a comment, please click here to sign in to your MathWorks Account or create a new one.