Tuesday, February 14, 2012

TDD is like losing-weight-hard & fails with converging prototypes

First off, I'm trying to develop better TDD habits, and changing habits is hard.

It is very related to losing weight. It is easy to get to the gym / eat less for a week or two and you are feeling great. You are a losing-weight-TDD rockstar. Then you hit that stressful moment(s) and all of a sudden you are back to old habits. But you are think that as soon as the stress passes, you'll get back to the gym / do some TAD (Test After Development), except that it is way harder to get started again.

I've also come to realize that there are times when TDD is very appropriate and times when it is not.
TDD is a lifesaver when you have clearly defined goals / user stories. You write your test to meet the acceptance criteria, write your class, and you are golden.

But when your goals are nebulous, like the client's core reason for a project keeps getting redefined, then TDD gets in the way. If I were to name this, I'd call this  "converging prototype" development. This is where they don't really know what they want, nor even the specific business problem they are trying to solve. They have a general pain point, or new idea, but it isn't flushed out (that is your, the developer's job). This is where you have a just in time backlog, and you are working on 1 week iterations. At the demo at the end of each week, the current application / prototype is really a "conversation starter" rather than a releasable item. Here is where TDD is not useful, as there is no goal. What are you testing?

Sure you could write tests for what you had, but at the moment it is still a prototype, or proof of concept. Core ideas are still highly vulnerable to massive changes. And designing / developing / AND testing in this phase sucks.

At some point, 3-4 iterations later, it is likely (hopefully), starting to converge on ideas / workflows / datatypes (yes, even datatypes couldn't be well defined initially). So now that we are converging, now is a good time to do some TAD.

Given it is not ideal, but testing after at least gets you tests, which is way better than no tests.
 This is also a good time to clean up / redesign where you are converging. Notice that I didn't say refactor, we are not necessarily trying to retain all of the functionality. We are still talking about a prototype.

We know that in another iteration or two, this prototype is going to cross over to be the actual app, but for now, we can be a little bit flexible with the "requirements".

In my commitment to more TDD, I've found that it is project specific goal. On my well defined project, I have 100% TDD and I LOVED it. On my poorly defined project, I started with about 80% TDD, and rapidly  dropped to 0%. The project has had 3 major direction changes, and the tests and codebase were nearly 100% irrelevant after each change.

I guess my next discovery is how well I write testable code without tests :)

No comments:

Post a Comment