My Views On Test Driven Development

Written By John Sonmez

I used to be a huge supporter of TDD, but lately, I've become much more pragmatic about it.
In this video, I discuss test driven development and what my current views on it are.

[responsive_video]http://www.youtube.com/watch?v=wryn6vFwqn8[/responsive_video]
[blank_space height='3em']
Full transcript:

John:               Hey, John Sonmez from simpleprogrammer.com.  This week, I want to talk about, yes, a technical topic.  I’m going to be talking about test driven development.  I’ve got a few controversial views on test driven development, but I’ll explain why I hold those views.  Hopefully, I’ll convince you at least to some degree that what I’m saying makes some sense.

I used to be a really big proponent of test driven development.  I used to really push for it really hard way back when hardly anyone was doing unit test.  Definitely, not very many people were doing test driven development.  I would often go into an organization or join a team, and I’d really push for test driven development and for unit testing.  This was a good thing.  I ended up improving a lot of the quality of code by pushing for test driven development and pushing for unit testing in general, but I was a little bit too strict about this.  I had code coverage requirements of around 95% asking that 95% of the production code be covered by tests.

Obviously, my views have changed on test driven development or I wouldn’t be telling you this.  They haven't changed a huge degree.  They’ve changed to be more pragmatic.  At least that’s how I think of it.  Let me explain, first of all, why I think test driven development is good, especially if you’re not doing any kind of unit testing at all, I’d encourage you to do some kind of test driven development.  That’s because the biggest benefit for me for doing test driven development that I found is it helps you become better at writing good code.

The reason why this is true is because when you write the test first, it forces you to use the APIs of your code.  It forces you to use that production code so that influences you to make the structure of that code better for being used and to be more understandable.  When we just write a bunch of code first where you don’t think about how it’s going to be used, we are guessing at how people are going to use it or how easy this is going to be to use.  When you write unit test first and then you write the code to make those unit test pass, you’re basically starting out by defining the API which is really valuable for writing quality clear code that’s easy to understand.

That’s really the big benefit for me.  Of course, there’s regression as well.  You can run those unit tests but I tend to think that regression is not so important anymore as far as unit testing goes.  Now, don’t get me wrong.  You still have automated test at a higher level, but as far as unit testing goes those regression tests really don’t prove much.  I found that in most complicated software systems when you unit test fail, we have to go and try and debug this and figure out why this unit test fail and most of the time it’s a false alarm.

I would say that there were very few times that a unit test has failed where I said, “Oh, this caught a bug.”  More often than not, I’ve gone and said, “Well, is this test actually correct?” or, “Oh, yeah, yeah.  That was expected,” or, “This mock failed.”  That’s the bad side of it.

Let me tell you what I think now.  I think now that test driven is like training wheels for writing good code.  It should be used in certain cases but not all the time.

A lot of times we end up just blanket and force test driven development.  What we end up having is a code that has tons of mocks or dependencies passed in.  We might use inversion of control or dependency inversion containers to try and pass all kinds of dependencies into our code, and then we’re just going to mock it up in unit tests when we’re doing test driven development.  This is a bad way to go because those tests become harder to write than the actual code and the test code that we write ends up being error prone and we could have bugs in the test codes.  Who is going to test the test code?  Are we going to write tests to test the test code?  No, we’re not going to do that.

I think it makes a lot of sense to be pragmatic about it.  If you’re just starting out writing code, you should definitely be doing test driven development for all your code because you need to learn how to write a good code.  When I started doing test driven development it really taught me how to write good code, how to write good APIs and really improve the quality of my code.

If you’ve been writing code for a while, if you’ve been doing test driven development, you will probably find this point where you start to feel like these tests aren’t adding value.  When you feel like tests aren’t adding value, this is my personal belief, stop writing those tests.  You want to be able to test code with your test driven development or when you’re writing a unit test that makes sense where it’s going to give you some value from doing that.  If you feel like it’s not creating value, stop doing it because chances are it’s not creating value.  You can refactor your code and structure your code in such a way that it makes it easier to write unit tests.

I’ve written up on my blog about … there are only 2 roles of code.  If you do a search for 2 roles of code, you will find my post.  Basically, I say that there are algorithms and then there’s a code that ties everything together.  If you can separate your code out better into those 2 types and don’t have it mixed together in classes, then you can write unit tests or you can do test driven development on the algorithm part and not have a lot of dependencies, not have to use a lot of mocks.  Those tests are going to be highly valuable and it’s just going to be really beneficial to you.

If you have everything mixed together and you’re finding that you’re having to write a lot of mocks and you find that your test code is really complicated, then you might really want to question the value of doing test driven development in that case.

Overall, with my view, I think test driven development is good.  It’s really, really good for beginners.  If you’re starting out you need to start practicing this in order to become better at development.  As you get more experience, you have to use your common sense.  You have to be pragmatic about it.  If you feel like the tests aren’t adding value or they’re just wasting time, then that might be true.

Well, I hope this video didn’t get you too ticked off.  I definitely have a different view on test driven development than I did earlier in my career.  Like I said, this comes from my experience.  If you disagree with me, let me know.  Send me a comment down below or send me an e-mail.  Don’t forget to subscribe to this channel and I hope you have a good week, and I will talk to you again next time.  See you later.