I'm part of the MathWorks consulting team based in the UK specialising in software architecture and testing (Andy's posted an article from me before). As part of some recent training I was delivering, I was contemplating this diagram that has been floating around internally for a number of years:
Hilarious, I know. The point being made is an obvious one, which got me thinking – if it’s so obvious that writing tests is a good idea, why don’t more people do it?
You need a test, so why don't you write one?
I came up with some possible reasons as to why people don’t write tests:
- They don't know how.
- They think it's difficult.
- They think that they don’t have the time.
- They haven't been bitten yet – maybe their code is not sufficiently large/complex/business-critical yet for a major outage to have occurred.
For the last of those points, you’ve got to ask yourself one question: Do I feel lucky?
Thinking of some of the customer projects I’ve worked on, people rely on the apps developed. If they stop working, they’re not going be putting lives at risk, but 10-100s of people might not be able to do their work. This costs time and money, and there might be reputational damage for the team that develops the app. I don’t feel lucky!
Test automation takes the luck out of software delivery
I think it’s widely accepted in the software industry that:
- Software is getting more complex.
- Our reliance on it is increasing.
- Development teams are getting bigger.
- Updates/deliveries are required more often.
We therefore need tests to:
- Validate that complex behaviour.
- Ensure robustness.
- Check code from the whole team works together when integrated.
By running those tests quickly and efficiently through automation, we can achieve those frequent deliveries with confidence.
Testing helps individual developers too
Here are five ways in which testing has helped me out on real projects:
- Testing has allowed me to make changes to large projects with confidence. I don't know exactly what the code does, even after a long time working on it. Sure, I can give an executive summary, or I can tell you the low-level details of the particular code I've worked on, but not everything in-between. That’s the domain knowledge of the customer’s engineers. By running the tests, I can be sure that everything still works.
- Tests have helped me to learn a new code base when I've been dropped into a project. They show me how the code is meant to be used and what the dependencies are.
- Tests encapsulate the knowledge I’ve gained and design decisions I’ve made as part of the development process, even on a very small project. I'm repeatedly amazed at how quickly complexity builds up – within a couple of hours of coding, I've lost track of what each piece of code is meant to do and all the edge cases it handles.
- Testing allows me to focus on requirements rather than implementation details. This is particularly useful when the implementation is not obvious. I can follow the process of identifying what it needs to do, writing a (failing) test to capture that information, doing some implementation, and then iterating – “red, green, refactor”.
- It helps drive software architecture through the creation of small, focussed, testable components. If the code is difficult to test, it’s almost certainly because I’ve designed it wrong.
Testing is now standard practice
In mainstream software development, writing tests has been standard practice for 10+ years. The “punks” have gone – professional rigor and craftsmanship is required. Writing tests goes hand in hand with writing the code.
It has been said (I’ve forgotten who – maybe Uncle Bob, maybe one of the many good talks from Cpp Con) that if you were to ask people in the late 90s or early 2000s whether they use version control, you would have got a patchy response – it wasn’t common place. Today, if you're not using version control, you'd be mocked! How could you possible develop anything without version control? Testing is going through the same transition. Don’t be the butt of the joke!
Whether your team or customer is demanding tests, as a software industry professional, you should be showing them the way!
Start writing tests today
You should start writing tests whenever you start a project. Complexity builds up surprisingly quickly so start testing from the beginning. It’s much, much easier to write tests as you go rather than coming back later and trying to do it.
Failing that, start now! If you already have a project without tests, don’t be put off. You can adopt an incremental or “fix as you go” approach to build up your tests. Writing tests doesn’t need to be a monolithic undertaking. Over time your test suite and coverage will increase.
A common question related to this is how to manage the transition from prototyping algorithms and workflows to a more formal implementation with tests. The objection goes “what’s the point of writing all these tests when the code is in so much flux?”.
Here, a judgement call is required. In the first stage you’re answering questions like “is this even possible”, “how do I actually do it”, and “is the result worth further investment”. In the second stage, you start to rely on the answers the code produces, or maybe others will want to run your code too. Either way, you’re starting to build a tool.
As soon as there’s a hint of stage two, start testing!
“But I don’t have time for any of this”
This common objection has been covered in many testing books and articles. To cite Kent Beck as just one example:
“The more stress you feel, the less testing you will do. The less testing you do, the more errors you will make. The more errors you make, the more stress you feel. Rinse and repeat”.
-- Beck, K. (2003). Test-Driven Development: By Example. Boston: Addison-Wesley
Think of that bug that appears late in the development process and takes days to track down. What if you had an automated test that pinpointed it as soon as it appeared? Think of a worse scenario – you’ve already released your code when a bug is found. How much time will that take to fix? I can guarantee it won’t happen at 9 o’clock on a Monday morning. Try 5pm on a Friday!
Now imagine an alternative world – you need to ship a new feature to meet a tight deadline. You integrate the code but are worried that it could break something else. But you remember you’ve got a test suite with full coverage that you trust. You run the suite and everything passes. You ship the code fully confident that everything works and go home on time.
So ultimately, do you have time not to test?
So how do you get started with testing in MATLAB?
How to do testing is an entire topic in itself. For now, I’m just going to point you to some resources to help you get started:
- MATLAB comes with the Unit Testing, App Testing, Performance Testing and Mocking Frameworks.
- There are lots more posts on this blog about testing, including the Database Testing Framework which I have written about previously.
- You can talk to our amazing training team about customised courses on testing.
- Have a look at our continuous integration options for running your tests automatically. There is support for Jenkins, Travis CI, GitHub Actions, Circle CI, and Azure Pipelines, as well as Atlassian Bamboo.
- If you want to get more into the theory, try reading Test-Driven Development by Kent Beck or Growing Object-Oriented Software by Freeman and Pryce.
Yes I know - the title is a misquote. The actual quote is "...you've got to ask yourself one question: 'Do I feel lucky?' Well, do you, punk?".
To leave a comment, please click here to sign in to your MathWorks Account or create a new one.