Chapter 12 of 15

Testing

Your future self will thank you, or curse you

Testing is extremely frequently mentioned as a thing that junior developers arrive knowing nothing about. In a bootcamp environment, that makes sense — you’re writing prototypes that you’re going to throw away. You don’t have the kind of long-term problems that testing is designed to solve.

But as soon as you get into a working environment, you need to be really good at testing, because everything you write is going to hang around forever.

Tests are a message to your future self

The person who’s going to be maintaining your code six months from now is going to be a completely different person from who you are today. You’ll have moved house, broken up with somebody, learned a bunch of new things — and you won’t remember a single detail about how this code works.

If you wrote good tests, the tests will tell you everything you need to know. They’ll confirm that everything is working as expected, and when you make a change, they’ll tell you if everything still works. Without tests, you’re just rolling the dice — “I think this changed things, but I can’t remember how any of this works, so… ship it?”

Tests slow you down now and speed you up later

Like security, testing takes time up front. You have to write tests as you’re building, not all at the end. It will slow you down, and you have to budget for it.

But tests pay back that investment many times over. Think about all the manual work of verifying that your application works: stepping through every screen of a checkout flow, making sure all the buttons work, checking that you can select from a dropdown, add and remove items from a shopping cart. That takes forever to do manually. Every time you change one thing, you’d have to do it all again.

With automated tests, you run a command, everything is green, and you know you’re good. Hours of clicking reduced to 15 seconds of test execution.

Automate your tests

If you can’t figure out how to automate a test, the next best thing is to write down the steps. Just document the manual process. You’re not going to remember six months from now what you used to do to verify this feature. Written test steps can at least be handed to an intern — and the most amazing thing about giving an intern manual test steps is that eventually they get bored and automate it for you.

But any test is better than no test.

Write evil tests

A very common mistake that new developers make is testing only the happy path. “I have a function called add. I put 2 and 2 into it and the answer is 4. Everything is cool.”

What if the first number is 2 and the second number is the complete text of Moby Dick? What happens then? Because somebody will misread the instructions and paste the wrong thing into the wrong field. Does your server explode? Does it return an error? Does it just print “2” because 2 + "Call me Ishmael..." equals 2 in JavaScript?

Any of those might be the correct behavior — but you need to know which one it is. Write tests where you’re afraid to find out what the answer will be. Test the cases that shouldn’t happen, because they will.

Keep your test data small and modular

Another common pitfall: the shared test database. You cram all the data for all your tests into one database, and over time it gets weird. Some code is broken, data accumulates, and eventually you have tests that only pass against the test database, or tests that fail locally but work in production.

Have small, focused chunks of test data that are specific to each test. Set up exactly what you need, run the test, tear it down.

Never have known failures

The only acceptable state for your test suite is 100% green, all the time. If you have 9,999 passing tests and 1 known failure, you don’t actually have a useful test suite. When someone makes a change that introduces a real bug in that same area, it looks exactly the same: one failure, the same as before. Except now it’s deleting the database instead of a harmless rounding error, and you’ll never notice because you built an expectation that “sometimes things are red” into your process.