Good developers know they should test their code. Too often, though, the tests get skipped, rushed through, or never started. There are some really common traps I’ve seen people fall into, and they’ll kill your motivation to test every time.
1. Should I use RSpec? Cucumber? Capybara? Minitest?
When you start a new project, it’s way too easy to spend a lot of time trying to pick the best tools. This kind of procrastination hides the fact that you don’t know where to start, and until you pick your tools, you can feel productive without actually being productive.
Instead, just pick the stack you know best. If you’re not experienced with any particular test stack, take the default–start with what Rails gives you. You can always add more later. There’s nothing wrong with trying out new tools, but it’s a much better idea to introduce them over time, as you get to know your project and workflow better.
2. Do I start with unit tests? Functional tests? Integration tests?
When you begin a project, you should have an idea of which features or screens should be built first. This is a great place to start! Pick the first thing off your feature list and write a failing integration test for it. This should tell you what kind of controllers and routes you’re missing, which means you need to write some failing functional tests. The controllers need data and logic to do their job, so you’ll write unit tests and your models next. Then, once you get your unit tests passing, the functional tests should pass, and so should the integration test. Now you can move onto the next feature.
If you have a testing process that always has the next step defined, it’s a lot easier to stay motivated. If you don’t have to make decisions, there’s less of an opportunity for procrastination to creep in.
3. I don’t know how to test this network code, command line utility, or rake task!
The easiest thing to do here is move as much code out of the file or class that’s hard to test and into a new object that’s easy to test. That way, the hard-to-test thing just creates and passes parameters to your new object.
Of course, you still have the original thing that’s hard to test. But it’s probably just a few lines of code now, and it should be easier to stub or fake it out.
4. “The project’s almost done, now I just have to write the tests for it!”
Every developer I’ve met craves shipping code. If the tests are the last thing to do before you can ship, you’ll write the minimum number of tests you need to feel kind of confident that the code works, probably. If you get into this habit, you’ll start to see tests as annoying instead of helpful, and it’ll be that much harder to motivate yourself to write them.
One of my favorite things about TDD is that it mixes the testing with the design and the coding, which means you start to see testing as coding, which makes it much more fun (and you get the benefit of having tests a lot earlier).
5. What if I’m doing it wrong?
The Ruby community is known for really pushing code quality, unit testing, and object oriented design principles. This is a great thing! Unfortunately, it means that it’s really common to feel an enormous amount of pressure to ship perfect code with 100% test coverage on your first try.
This makes it really hard to start a project, especially open source, where you know other people will see the code. What will people say if they see that it doesn’t follow all of the SOLID principles? But there are a few things I’ve learned that have helped me deal with this pressure:
- Every good developer writes code they’re embarassed by later.
- Good code that ships is infinitely better than perfect code that doesn’t.
- Some people are just jerks and will make fun of your code. This really sucks. It’s ruined entire weeks of mine. But good developers want to help you instead of criticize you. And I’d bet that if you showed that code to a programming hero of yours, they wouldn’t make fun of it–they’d help you make it better.
What else have you noticed?
Which of these traps have you fallen into? What’s helped you pull yourself out? And are there any that I didn’t mention that you’ve noticed?
If you do recognize yourself in any of these traps, what are you going to do to get yourself out?