Stories about Software


ChessTDD 31: Look, We Caught a Bug!

A bit of time went by between when I recorded the code and when I narrated it, so pardon the unusual amount of rust there. But this episode was particularly interesting because an actual bug emerged and I fixed it. Yay for acceptance tests. After that, a second bug emerged, but I ran out of time. So there’s definitely a todo for episode 32.

What I accomplish in this clip

  • Got away from the C&P implementation of “then” for the new style of tests and implemented a usable one.
  • Discovered and fixed a bug in king’s moves.
  • Discovered another bug to fix next time.

Here are some lessons to take away:

  • When you’re stumped by behavior, particularly in integration tests, the continuous testing tool can help you run experiments very quickly.  Add a precondition assert to verify that your assumptions are correct.
  • TDD is not a catch-all against bugs, by any stretch.  I had a dumb bug in the implementation of the King class that I failed to catch, and everyone following along failed to catch (assuming someone would have reported it, anyway).  It wasn’t until I started simulating real production usage that these bugs started to be revealed.  Acceptance tests are critical.
  • The balance between ATDD and TDD is beneficial.  You’ll see going forward that when I find problems, I tend to use increasingly specific tests the way that you might be used to using step-through in the debugger.  Narrowing the scope of the problem with tests rather than the debugger has the advantage of leaving a trail of breadcrumbs that become guards against regressions as you go on.
  • This ATDD/TDD stuff works.  As you can see, I caught 2 bugs that could have escaped into production.
  • Never commit with red tests, obviously, but I also say never take a break with red tests (the way I would have to between clips).  If you have to go, comment or delete that red test, so that you can start fresh with green next time and reintroduce it.

Newest Most Voted
Inline Feedbacks
View all comments
Amitai Schlair
9 years ago

Haven’t watched yet, but depending on the situation I might disagree with that last point. One way I make context-switching less expensive for myself is, once I get to green and commit, leave myself one new red test — basically fail("hey goofball, the next thing you wanted to do was in Foo::barMethod()"). Then, when I come back, I skip the procrastination step entirely, and the context-reloading step is much faster.

Erik Dietrich
Erik Dietrich
9 years ago
Reply to  Amitai Schlair

For commits, a broken build seems like a high price for the team to pay for me to remember where I left off. For me personally, when taking breaks, the green invariant forces me to prefer working toward passing tests as a stopping point. I don’t need to optimize for getting back to where I left off if I get used to leaving off green.

Amitai Schlair
9 years ago
Reply to  Erik Dietrich

Shoulda been clearer. About committing, I never want to inflict known red tests on teammates. About stopping, preferably somewhere green so I can commit. About continuing, preferably with a single not-checked-in red test that reminds me what I had planned to do next, because I’m forgetful but I’ve managed to train myself to run the tests pretty often. 😉 Since it’s not checked in, once I see my past self’s reminder to my present self, I can immediately revert to my last checked-in state, see once more that it’s green, and proceed in the direction I’ve now managed to remember.… Read more »