A reader asks:
My boss knows about TDD but won’t allow us to use it because he thinks that it is just a passing hype that everyone talks about but no serious, big projects actually use it on daily basis. How could I convince him that it is not so?
Excellent question which takes me a bit by surprise, as I can’t imagine my boss dictating how I write code. I don’t have an answer but here is what I think I would do if I was in this situation. However I wold also like to encourage other readers to share their thoughts on this topic and offer suggestion in the comments.
Arguments don’t work
There is no magical argument I can make to convince someone that TDD is a good idea. It is not a debate of logic, but rather debate of experience. We are not arguing here that 1 + 1 is 2, but rather that if you follow these practices than the result is subjectively better. Since there is so much subjectivity in this, people need to experience TDD to understand its benefits. It is very hard to learn TDD by someone trying to learn it from a book. TDD is more like riding a bike. You can read books on how to do it, and you can have silly arguments with theorist that you cant ride a two wheel contraption because it is inherently unstable, but nothing makes them believers like living through the experience of learning to ride a bike. The first time you ride a bike it is a very clumsy experience, and I would argue that it takes hours of falling and uncertainty until you are better at it than walking. So don’t expect TDD to be any different. It is a skill that takes hours of practice to master. So don’t argue with anyone over your experiences, rather make others live through the same experience. Have them come to the same conclusions by showing them.
Make sure you know what you are talking about
Nothing is worse, than someone selling me on something which they fully don’t understand. Make sure you are reasonably good on TDD and have built a reasonable size application before you try to show someone else how to do it. Imagine someone who has only seen others riding the bikes trying to teach someone else. My guess is that you will only get the person frustrated. For this reason built a small app in your free time with TDD. Your first test will be the hardest, and at times you will think this is way more trouble than it is worth. But keep in mind that it is a new skill which you are learning, and it is the reason why you are struggling. You have been developing code for years the old way. What makes you think that you can pick up TDD over night? TDD makes you thing about tests first, something which you have never done. It will not come easy, but in time it will become second nature to you. For me that took about a year, before test first was a natural flow of things.
Create a small project on show your boss how helpful tests are in refactorings
I cannot overstate the importance of learning the TDD on a brand new project without any deadlines. Start something new in your free time and start building it with TDD. Use it as a learning experience. You will discover all kinds of things about how to best write code. You will get a feel for tests which are helpful and tests which only get in the way. You will learn how to thing abut the problem from test first perspective. You will realize how important it is for you to not get ahead of your tests. And finally you will discover that your code looks nothing like what you have envisioned. The code with tests looks different. Than try to refactor something and you will see how some tests are in your way and some tests are helpful. You need to live through these experiences so that next time when you are test driving a class you can say, wait, this test looks like that other test I wrote and it was in my way when I was refactoring, but I know how I can write it differently so that it will be like this other test which turned out to be helpful. You can only have these debates in your head if you have built something with TDD.
If you try to bring TDD to an existing project, it may only fuel your bosses feeling that TDD is not useful. Since you will be struggling a lot at the begging. Again, it is a skill and it takes a while to develop.
Tests help design
We all believe that good code is reusable code. For this reason most of us add all kinds of interfaces and abstraction in the name of reusability. But how much code have you actually reused compared to how much you have written. I say it is tiny fraction, very close to zero. One reason is that we only think we have reusable code. But tests are a great equalizer in this. Tests force you to write reusable code so that you can use the class in production and in a test scenario. If you can’t write a test, it means that you don’t have a reusable code. If you write test first than it is very likely that the code will be reusable, after all you just used it in tests and in production. This is the single reason why tests first creates better design. On the other hand if you write code as you always have and you will most likely end up with hard to reuse code. If you try to write a tests afterwards then at best the test is an afterthought which is hacked on top of the production code. This test is very unlikely to help you when you are refactoring since it will very likely be a false negative.
Hardware folks have figured this out
Did you know that average chip can have as much as 50% of its silicon dedicated to testing? Why is it that every discipline out there takes testing seriously except software. I believe it is because of the apparent inexpensive nature of fixing bugs. A new rev of silicon is extremely expensive. As a result most companies can only afford to rev it about 5 times. Can you imagine writing code such that you are only allowed to run the production 5 times? Yet the hardware folks cant imagine designing chips any other way. In software cost of another rev is close to zero. But it is not zero, and this is where people get into trouble. What is another build cost us? Nothing, (almost) and so it becomes a death by thousand cuts. The more complicated the project the more likely it is that a fix in one location will cause a bug someplace else getting into an endless cycle of regressions. Tests help here. But again it needs to be experienced.
If you get stuck, than spike
Sometimes you just have no idea how to write tests first. There are a lot of reasons for this. So we revert to good old fashion hacking. There is no problem with that as long as after you learn by hacking, you go back and write the tests, or preferably throw it away and test drive it. We call this ’spike’. I get to do this quite a lot when faced with new technology or environment. Just don’t let this become the way you develop software.
Vote with your feet
If your boss is getting into micro-management of how you do things, and you have tried everything else to explain your position, you always have the right to vote with your feet. Last time I checked, us software engineers are in high demand, so there is no reason to work for people which are being counterproductive.
What do you think?
What do the readers thing about how they could influence others in getting them to develop software with tests? Please leave your comments so that we all con learn from each other…