Sunday 6 January 2013

Test Driven Development - objections, part 3

Welcome to part 3 of my post about TDD objections. Today's gonna be the last part of my comments on common objections to TDD. Again, I'm not an expert on these things - I'm merely writing down my thoughts and experiences, so any comment is appreciated! I'd love to know your objections or which ones you're most often getting into, how you deal (or dealt) with them etc.

Where did we leave the last time?

Ok, let's take on the next set of objections from the list:

  1. Not enough time
  2. TDD will slow us down, because we'll have to create a lot of additional code
  3. TDD will slow us down, because we'll have to maintain a lot of additional code
  4. We don't have the necessary skills or experience
  5. We don't have the necessary tools
  6. (This one is unit testing specific) There are already other kinds of tests, we don't need unit tests?
  7. It's very hard to perform with legacy code
  8. I already know how to write a testable code, TDD will not really improve my design
  9. We've got enough quality and we're doing fine without TDD
  10. My manager won't let me do TDD
  11. There's no "scientific proof" and enough research on whether TDD really provides a return of investment

The ones I'm gonna talk about today are the one marked with strong text. Let's go then!

8. I already know how to write a testable code, TDD will not really improve my design

Personally, I know several engineers who actually learned how to write testable code without TDD. They usually added unit tests after code and, over the time, learned to structure the code in such a way that it allows dependency injection, contains small number of private methods etc. If your mates are on this level, it's really not that that bad! However, I observed few deficiencies of such approach when compared to TDD:

  1. It is actually harder to learn how to write testable code without TDD. Also, many hours are wasted on refactoring before one grasps how to do it. In TDD, testability is built-in. So why choose the hard way?
  2. Test-first is often referred to as an "analysis step". You get the chance to take a step back and analyze what should the work-flow be, which behaviors have to be supported etc. Sure, one can use programming by intention to design classes and methods in an outside-in fashion, but when coding, you always see just the current method, or the current statement. In contrast, the unit spec/test forces you to consider whole class from object creation through invoking triggers up to getting a response. This perspective is more useful for analysis (and design) purpose and it is retained each time a new unit-level spec is written.
  3. The benefits of using TDD as a design-aiding tool are not only that you make testable classes that allow dependency injection. The benefits are also in making you focus on just what you actually need, without bothering you with what you don't. In TDD, you state your expectations one at a time, striving for the simplest solution. This leaves less room for over-generic, "just-in-case", framework-like overdesigned structures. Now, don't get me wrong, generic designs are a great and even necessary where genericity is needed and well justified, however, I believe that overdesign is almost as bad as underdesign.
  4. There are other things I have already written about that tend to happen in test-after approach

9. We've got enough quality and we're doing fine without TDD

This was actually responded to by James Grenning on his blog and the response is so good that I have really nothing to add. Go read it.

10. My manager won't let me do TDD

Putting things this way is usually a mental shortcut that might mean different things depending on the context. The most literal interpretation (like receiving a direct order not to do TDD) is almost never the case.

Sometimes, this is merely an excuse. Putting the blame or responsibility on the supervisor is one of the most popular ways of saying "I want someone to take the responsibility instead of me" and may be an example of Cover Your Ass Engineering.

Let me share with you my experience on the topic: in my first project, I thought my boss won't allow me to refactor. But I did - and in the end, no one questioned. In my second project, I thought my boss won't allow me to use smart pointers. But I did - and I was thanked for this. In my third project, I thought my boss won't allow me to use mock objects. But I did - and it was recognized. What's the moral? It's that often it is you who has the authority to make technical decisions. when you put responsibility on people who don't have the authority, they will hold back - this is natural. So go ahead, make the decision and take the responsibility. If it ends with success, take the gratitude. If it fails, take the blame. That's the best way to achieve something.

Sometimes, such complaint may also mean lack of support. In such situations, you can try out two steps that I know help dealing with this:

  1. Build your position - either internally (within the company) or externally (within the wider community) or both. This can be done by participating in open source projects, creating a blog, taking part in conferences, organizing trainings etc. When you are recognized in the community as an expert, your authority rises and people will get persuaded by you more easily.
  2. Instead of hoping your boss will create a plan and make you a part of it, create your own plan and show your boss how he can be a part of it. Show your boss what you want to achieve and what you need from them in order to be able to achieve this.

This whole section put in short is: "you're the one in charge. Believe it!".

11. There's not scientific proofs and enough research on whether TDD really brings any benefits

Oh really...

Let's put it this way - I could really try to convince somebody by listing the references, trying to analyze them, pick some arguments etc. and wait for the other person to say "Ok, I'm convinced" instead of something like "that doesn't convince me, because my case is special and these things do not apply". I could really try and do this.

But I won't. Why?

I won't, because I think this argument is usually raised in highly unfair ways. Ever wondered why anybody needs scientific proof for TDD while they didn't need any for daily stand-ups or four-week sprints, or retrospectives or any other agile or non-agile practices they've already incorporated? Can they show you the scientific research that led them to adopt all these techniques and methodologies?. If so, THEN let's talk about scientific proof for TDD (and it may be a very fruitful discussion). Otherwise, no.

From my observation, the "need for scientific proof" arises when someone simply doesn't want to adopt TDD and is using this argument as a mean to say "I don't wanna do this, unless you prove me that I have no other choice". There may be some reasons why this person doesn't want to try out TDD and they may be VERY good (and worth discussing), but the "scientific proof" argument itself is usually a facade.

Summary

This article ends the series of my comments on common TDD objections. At least for now. I hope you had as much fun reading this as I had writing.

See ya!

No comments: