You’re excited about the app you’ve made. There’s just one problem – you don’t have any tests. You wanted to write it using Test-Driven Development, but you didn’t quite know where to start. So you’re stuck. Where do you go from here? How do you get from an app with no tests, to writing your apps using TDD?
Test the code you already have
You have a bunch of code with no tests. But that doesn’t mean you can’t write your tests now, against the existing code. So start testing the code you already have, to make sure your code works the way you expect it to work.
It’s not TDD. But testing existing code will help you learn TDD:
-
You practice thinking about edge cases and error conditions.
To write tests without spending years testing every single possible input, you have to think about where the code is most likely to break. If the method you’re testing takes a string, what happens if you pass it a symbol? What happens if you pass it
nil
? And if you’re testing a function that divides numbers, you’d better test it with 0. But you probably don’t need to test it with 1 and 2.After you write enough tests, you’ll start to predict where your methods are most likely to break. And once you start TDDing, you can use this skill to write robust tests that force your code to better handle your edge cases.
-
You practice writing well-structured tests.
When you write tests after-the-fact, you can try different patterns for structuring those tests. The code you’re testing is already there, so you can focus on your test, and how it’s written. And once you learn some good patterns, you’ll write better tests when you don’t have the code to lean on.
-
You discover the things that make code hard to test.
As you write more tests, you’ll begin to sense which areas of your system will be the hardest to test. When you notice those areas, you can highlight them as places that need refactoring. Even better, you’ll start to write more testable code the first time.
Once you know what easy-to-test code looks like, you can TDD easy-to-test APIs with that knowledge. And that will help you build your apps faster.
Ease into TDD
You can use test-after to build skills that help you learn TDD. But you still want to TDD pieces of your app eventually. And there’s a simple way to ease into TDD, and still lean on existing code: write regression tests.
Regression tests keep you from breaking code you’ve already fixed. The idea is pretty simple. Whenever you hear about a bug, instead of clicking around in the browser to reproduce it:
- Write a failing test to reproduce the bug.
- Run the tests, and make sure they fail (because that bug still exists).
- Fix the bug in the simplest way possible.
- Run the tests, and make sure they pass.
- Refactor your fix, if necessary.
This is a lot easier than TDDing a new system from scratch, because you’re just test-driving a change to code that’s already there. You build the habit of “Red, Green, Refactor” that is the essential loop of TDD. And from here, TDD is a shorter step away than trying to go straight to TDD from no tests.
From nothing to TDD
An app without tests isn’t a bad place to start. When you test existing code, you’ll learn a lot of what you need to write good TDD tests. Test-after is easier than TDD at first, because you don’t have to imagine APIs that you don’t know how to design yet. And once you decide to bring TDD into your app, you can ease into it with regression tests.
So, if you don’t know how to TDD the system you’re imagining, keep writing tests. Even if you have to write the code first.