While it is a well known best practice in software development, most of us still don't write automated tests for our code. The reasons for this are many, with “lack of time” one of the most common reasons cited. That said, let me share with you the top 10 reasons why I believe everyone should write tests for their code.
I'm not going to get into which testing suite or framework is the best, instead I'm going to just state that I honestly don't think it matters. In my experience, the important thing is that tests are written, regardless of what type they may be.
Top 10 reasons to write tests
1. It's better than manually repeating 1,000 steps
It might sound obvious, but it's worth stating. Knowing that a set of tests will step through all sorts of different scenarios and use cases, all by running a single script or clicking a few buttons in the admin, takes a huge amount of pain out of manually checking lots of different scenarios for a contemporary Drupal module. After years of manually testing each of the modules I maintain, never mind the hoard of modules I contribute random patches to, knowing that there's something which will automate this has lifted a tremendous burden off my shoulders.
There's also the additional certainty that the steps will be followed in the correct order. Instead of worrying about whether you're going to accidentally select the green sash instead of the purple sash when adding a product to a cart as part of a 50-step QA process, you'll know that every time the purple sash will be selected. Or whatever.
2. Avoid regressions when changes are being made
While working on changes to the Fieldable Panels Panes module a few months ago we didn't want to run the risk of changes breaking functionality for existing sites, given that we were about to make a major change to how the module behaved with Panelizer and editorial workflows. Having tests to cover these scenarios assured us that the new changes weren't going to cause problems.
3. Learn how the module works
While writing tests for Metatag last Winter I learned more about how it worked, including several things I wasn't aware of. This was quite surprising to me as I'd been maintaining it for several years at that point.
4. Confirm the module works the way you think it does
Two different bugs were identified by people in the Metatag module. At first I dismissed the bugs as being silly - I thought there was “no way” the module could have had these two bugs given how all these other tests showed how it worked correctly and how I believed the module's internal APIs worked. Because I didn't have existing tests to cover those exact scenarios I took the time to write some, just to be sure. Once I had some tests in place, however, the bugs showed themselves! The fixes ended up being quite straightforward, but I needed to prove my certainty was misplaced.
5. Help identify and confirm bugs
When it was reported earlier this year that there was a bug in Webform's file handling for anonymous users, I wrote a test to document how the file upload process should work. This then gave us something to work against - when the tests would finally pass we would know we had fixed the bug. The bug then was identified as being in Drupal core itself, so again I wrote some tests to confirm the core bug, which some others followed up with a fix to the actual bug. So, even if you're not sure how to *fix* a bug, being able to concretely reproduce it in a test is a huge help.
6. Help prove the module's stability and worthiness for a site
As part of identifying what software to use, thought should be given to whether there are tests available. Software with tests will typically be more stable than software without. As mentioned above, having tests helps avoid regressions as changes are made, so you can be assured something your site relies upon won't stop working because of an update.
7. Improve your development skills
The more you understand how something works, the more you'll be able to mould it to do what you want. I've found this to be true with several of the projects I've inherited from others - the more of Panelizer and Metatag I worked with and understood the better my own changes became.
8. Automated tests integration in drupal.org
Every project on drupal.org can enable automated testing. When this is enabled any patch that is uploaded will have the project's test files ran against the codebase, completely removing the need to set up a test instance of the module locally. This can dramatically lower the barrier to contributing good and reliable code, and to help improve other code so that it is good and reliable, as an average contributor doesn't have to know a simpletest from a swimming test. Maintainers also heavily rely upon this to guide them on what changes to commit, and when a patch needs further work.
9. The more you write, the easier it is to add more
As more tests are written you'll start refactoring the different test methods and combine code, creating reusable methods that can be used on more tests. That will then make it so much easier to write more tests for the project. Soon you'll find yourself deciding to not make any new changes until there's a reliable set of tests to confirm it works correctly
10. They're fun to write
I've honestly taken a great deal of enjoyment over the past year out of learning to write tests for the modules I maintain and for other contributions. It's just great knowing that I won't mess up Metatag's revision or language handling again, or Panelizer's basic entity saving & updating, or Imagecache Token's value generation - there are now a growing number of tests for them. I can now carry on and work on fixing other bugs, adding new functionality, and adding more tests, and be more certain that my proposed changes will work as intended.
Stay tuned for more!
Hopefully now you'll have some understanding on why automated tests are a useful thing for a Drupal project, or any project for that matter. Check back soon as I share some tips for writing tests for Drupal.