Friday, March 20, 2009

TDD Adoption

I've been doing a lot of reading about Test Driven Development and how to use and apply it and found some of the most revealing material while reading about Behaviour Driven Development. I was reading this Introduction to BDD and the TDD Adoption Profile mentioned at the top of the article was the catalyst for this post. This will make sense to anyone who knows anything about BDD since BDD is basically an attempt to relabel TDD to help people use it more appropriately.

What I hope to do here is highlight some of the key areas that seem to cause developers to fail while using TDD or fail to adopt TDD. I get the impression that development teams attempting TDD often end up not using it properly or consistently or else quitting.

Developer Buy In

This could be a failing point of any development technique but I think it affects TDD more so because of the requirement to write tests first. If the developers don't buy in, they won't write tests and will continue to just develop in whatever way they are accustomed to.

Focus on Testing

Of course there is a focus on testing in TDD! The T stands for Test, doesn't it? This was one of the biggest realizations for me while reading the BDD Introduction mentioned above. They mentioned that most developers get to step 4 in the TDD adoption profile and stop there missing the benefits of steps 5-7. I think this was a big realization for me since I was probably still at step 4 in my own acceptance of TDD. After reading steps 5, 6 and 7 and reading about how BDD is basically TDD with less focus on testing and instead a focus on behaviour I began to see the real benefits of TDD. So to oversimplify things, the BDD folks are basically rebranding TDD to focus attention where the the real gains in TDD can be made. This leads me to wonder then if a developer would gain more by first being taught about TDD with this emphasis in mind rather than having to get there on his own, making these realizations as he goes. I can see how the personal realizations would carry more weight than just being told about these things in advance but wouldn't foreknowledge at least increase the likelihood of the realizations occurring?

Learning TDD on the Wrong Project
I don't mean to suggest that TDD only works with certain types of projects but I'm convinced that there will be a greater chance of adoption if the selected project is a new one or has had very little work done on it. The reason I say this is because the first step in TDD is to write tests first and not to write code you don't have to. So writing tests for existing code can at times seem pointless or at least more work than it's worth when you already have a working application (although there is merit in having thorough unit test coverage) and writing tests for new code requires the team to develop using new techniques on an application they've likely already spent a lot of time on and are fairly adept at debugging. I'm not suggesting Unit tests shouldn't be written or that TDD can't be used on an existing project, I'm just pointing out areas where I have seen resistance to TDD adoption. For a team new to TDD it may be better to start fresh. Starting fresh may also help the team feel more inclined to experiment with this new method whereas an existing project will already have set expectations the team is accustomed to. I appreciate that step 1 in the TDD adoption profile is about starting by writing unit tests around their code so perhaps a first foray into TDD is best done on an existing project but I would argue that it would be better to not refer to it as TDD at this point in time because it is actually not yet TDD. Instead I would call it what it is and that is writing unit tests to help improve the quality of the code being tested. It is not yet TDD because TDD requires that you first add a test for the feature you want to addand then after seeing the test fail you implement the feature.Poorly Designed Code is Hard to Test

One of the realizations while learning TDD occurs when the developer discovers that TDD is in fact a design process that helps them define the application's API. Developing in this way will likely produce better code than was previously being produced and of course have tests written for but my point here is that if attention is also given to applying best practices like proper object oriented techniques and design patterns then TDD adoption is smoother and the TDD process itself becomes easier. Take MVC for example. When followed correctly all business logic should end up in the Model which makes things much easier to test, especially if the model was created using object oriented design principles.

I know some of what I've said are problems that are addressed by using TDD and in realizing that it hopefully increases the value of TDD in the eyes of those trying to use it.

Some might ask, why not just use BDD? My response at this point would be, I don't know, why not? Perhaps frameworks for BDD are not yet as established as those used in TDD. Maybe we should all switch to BDD. Or maybe, TDD works just fine provided we shed light on more than just the testing aspect of it.