Gears Within Gears

Seek simplicity, and distrust it.

Do unit tests find bugs?

Posted by Brian Guthrie Tue, 10 Feb 2009 01:50:00 GMT

Suggested controversy background reading: Joel hates tests, Uncle Bob is incredulous, Kent Beck is offended, the VP of software development for Justin.tv shoots proudly from the hip, Jay doesn’t see the big deal but blogs about it anyway, and here’s little old me, exxagerating only slightly. Hat tip to every single developer on Twitter.

So, bugs. Do tests find ‘em? Good lord, yes. I don’t know what kind of unit tests you write, but mine find bugs all the time, though not generally until I try to change something ‘twere better left unchanged. I can’t begin to count the number of times a well-placed test has saved my own individual slice of bacon or the collective bacon of my team. Maybe I’m no rock star, but most of your team members won’t be, and a good rock star may well make a bad teammate. A robust test suite is the critical difference between me being enthusiastic about improving my team’s code and being terrified of doing so for fear of breaking something.

And finding bugs isn’t even the best reason to write tests.

  • They communicate intent and serve as a living, breathing specification for a codebase that may not have one.
  • They allow you to reason about code that hasn’t been written yet.
  • They demonstrate how best to utilize what’s already there.
  • They bring discipline and coordination to your process.

Two things really brought me around on testing:

  • I’ve worked on several large, complicated codebases written in a dynamically-typed high-level language.
  • I’ve had several great mentors who’ve demonstrated to my satisfaction the zen-like benefits thereof.
  • Every time I have written code without testing it as I go I’ve come to regret the decision, without fail, even on personal, why-bother-testing stuff. I honestly don’t know how you people get a decent night’s sleep.

Stuff can break:

  • Tests that once described the behavior of a particular module in a very granular fashion start to inhibit your ability to change evolve code in reasonable ways. Write more robust tests.
  • Slow tests can result in a slow build cycle. There are technical solutions for this. (You do continuously integrate, don’t you?)
  • 100% code coverage is hard to achieve. Code coverage is a funky measurement and a perfect score is no guarantee that you’re actually perfectly tested. I will also happily acknowledge that striving for it seems to yield diminishing returns. I try to stay above 90%, 95% if I can swing it, but I don’t let not hitting 100% bother me.
  • Plus all of the other triumphs and tribulations that go along with maintaining a good test suite, as with any other body of code.

If you’re still undecided, well, it helps to work with someone who’s done it before.

Posted in | no comments |

The Way I Pair

Posted by Brian Guthrie Sat, 13 Dec 2008 21:22:00 GMT

I figured I’d throw my hat into the ring and talk a little bit about how I pair, and what I’ve learned about it.

My first introduction to pair programming actually came in my freshman year of college: our professor required everyone to pair up on all homework assignments, and to keep that pair through the entire course. Me, I hated it. Neither of us knew anything and we ended up working at cross purposes. One of us would end up doing the work the other didn’t understand. By the end of the semester, we wanted to strangle each other. Pairing was a chore rather than a boon. I had much the same experience several years later, in another course taught by the same professor.

I’ve seen a huge difference between pairing in college and pairing out of it. Here are some things that would have made a tremendous difference to my pairing experience in college:

  • Design your work environment for pairing. It’s hard to get a rhythm going with two people huddled around a small laptop screen. Open workspaces, mirrored monitors and keyboards, and ready access to coffee and snacks all promote a nice pairing environment.
  • Set ground rules. I happen to think that certain ground rules, like keeping laptops closed while pairing, make a tremendous difference. When your laptop screen is open you (or at least I) tend to get distracted by other things, like incoming IMs and email. These don’t suck up a huge amount of time but the pair suffers from the overhead of the distraction, and it’s easy to lose your focus. If you need to pull up API docs, do it on the main screen.
  • Maintain core hours and stick to them. It’s important that the entire team be present and focused at least some of the time.

These are things that you’ve probably seen before; they’re team-level recommendations, and TW does a pretty good job of sticking to them. Here are some more specific practices that have helped me on the individual level:

  • Ping-pong. Just knowing that it was possible to set up a rhythm made a tremendous difference in my approach and productivity.
  • Communicate. I love it when my pair stops me to correct my mistakes, because I find the bug that much more quickly. It also makes the coding process feel more collaborative to me. Some people hate it, though, and I tend to irritate the dickens out of those people, since it’s what I do by default. But I’m not trying to be a smug jerk, and would be happy to stop if you just let me know it bugs you.
  • Rotate. You’ll get sick of anyone eventually if you spend too much time with them. Switch it up. If switching is painful, do it more often; it’s evidence that not everyone understands the codebase as well as they should.
  • Come prepared. You’ll be a more effective pair if you’ve taken some time out before you join the team to understand the domain and the technology. No one expects you to be an expert, but if you’re familiar with the fundamentals it makes the whole process smoother.
  • Put the brakes on occasionally. Don’t be afraid to hold up story work to check docs, root out bugs, or just ask your pair to explain something. We don’t pair because we think it grants us raw development speed; we do it because it produces better code and a better team, which will get software out the door more quickly in the long run.
  • Time-box your discussions. If you can’t agree on something, flip a coin or ask another pair for their opinion. Remember that most decisions aren’t final. Agree to try something that you don’t like and then take some time later to re-assess that decision once the implications of it have been played out (and tempers have cooled).
  • Finally, take breaks. Take a walk. Grab some coffee. Eat lunch with someone other than your pair. Do some coding outside your pair to try out new ideas or dive down into a part of your codebase you don’t understand.

Good luck!

Posted in | 1 comment |