Automation Lessons

When creating software, ensure there are working harnesses for testing, installation, and upgrade first.

This is a lesson from long ago that has stuck with me and been proven valuable over and over. I recently shared the following with colleagues.

As development technologies have matured the lesson has evolved to assert the harnesses must be automated and the automation must run before changes are merged.

Throughout my experience with our previous teams we frequently ignored this lesson for a variety of reasons, all of which are at least inconvenient but most of the time invalid:

  1. We’re in too much of a hurry to add tests, we need to get this out now.
  2. This is too complicated to automate.
  3. This is too time consuming to run in pull request workflows.
  4. This is too resource consuming to run in pull request workflows.

Most of these reasons only feel correct when viewed from the perspective of the individual developer who needs to do the work to make things go, or is waiting on CI for the pull request to merge.

For other developers, other teammates, or the customer (who might be a “real” customer, or someone internal) these reasons don’t have much relevance.

If you don’t test now, then it is the other people who end up doing the testing for you, finding issues. Turnaround time on resolving those issues is vastly higher than it would be otherwise, the other person has to do extra work to get what they want and you have to do extra work to understand the problem. Instead you could experience the problem yourself, sooner, and not cascade the wasted time to others. That wasted time adds up, exponentially, and any time savings you thought you were getting by pushing things out quickly are dramatically shrunk.

If you don’t automate the tests or the installation, you then have to spend time doing those things by hand. You do. Your teammates do. The customer does. And no matter how much you think “oh we’re only going to do this by hand once or twice” that always turns out to be a lie.

Even when it doesn’t turn out to be a lie, eventually you’ll need test and installation automation. Paying the price up front has many advantages:

With regards to “too complicated to automate”. Sit with that for a moment. If that’s true, what does it say a) about trying to use the software, b) about trying to maintain the software over the long run. Let’s be honest here.

Okay, say you’ve managed time well enough to have built tooling that can automatically test the software to a significant degree as well as automatically install it somewhere. Great. Then that tooling should be required to run (automatically) for any pull request and required to pass all tests and properly do an install before that pull request can merge to its target. Ideally it would also do an upgrade. That is what continuous integration means.

We’ve argued about this being too human-time and compute-resource consuming many times over. Meanwhile:

We often find ourselves saying a version of the following:

Once we have it working in context X we’ll look into making it work on pull requests.

If you can only take one thing (but please take more!) from this document take the awareness that that is backwards. Instead:

Make it work on pull requests. Once it is working there, use it in other contexts.