We all know that using TDD is the best way to reduce debugging time. We also know that if you have a bug, and you have tests for your system, it’s easier to fix the bug. By either writing a short needed test or debugging a simple test (rather than the entire system), we counter the programmer productivity nemesis – the debugger.
It’s interesting to think about it this way – our main tool is the one that bogs us down when we want to get productive. I guess it’s another case of how you use the tool.
Kent Beck, of XP (extreme programming) fame, posted an article about an innovative way to find bugs. You can guess – it’s starts with a test. The test fails and reproduces the bug. Now, in most cases, we would start stepping into our code with the debugger, opening enough watch windows as we can, until something catches our eye – thinking “this data should be different” or “this line shouldn’t be here”. Because I’m lazy, my punishment is to repeat this, since I tend to jump between big pieces of code. So finally, after some kind of “binary search” debugging, I get to the problematic line of code.
Sounds familiar?
Kent suggests this repetitive process, that does not involve the debugger:
- Inline a non-working method in the test.
- Place a (failing) assertion earlier in the test than the existing assertions.
- Prune away parts of the test that are no longer relevant.
- Repeat.
I encourage you to read the entire example. The crux is: What I do in my brain during my “binary search” debugging, he’s doing with a text editor. And methodically, I might say. What you are left with is a short concise test that represents the bug, with a very clear way to see the offending line. No debugging needed, just editing. It’s not a substitution for the original failing test, it’s an addition.
In his post, Kent says the most time he spent was on the editing. Apart from moving code, it also requires making private methods public. But with tools like Resharper or Refactor! this may could be a breeze. (just need to revert the code afterwards). Right tool for the job. Again.
Now for the Isolator angle: Without pruning, at the test level, you can write at least one type of assertion like this: with Verify.WasCalled and family. What’s really missing today is an API like this:
1 |
Isolate.Verify.WasCalledWithAnyArguments(()=> form.IsDirty).AndReturned(<span class="kwrd">true</span>); |
With these types of assertions, you do not need to edit your code, but place assertions in your test (like check points). You run your tests, don’t debug, and narrow the search until you find the offending line.
What do you think? Would this API be useful for you? Is Kent’s way the new TDD? And are we ever going to find out what Jack Bauer does after-hours?
[Via ObjectMentor, Uncle Bob]