Home > Programming, Unit Testing > The importance of unit tests

The importance of unit tests

A few days back, one of my friends asked me following questions related to unit testing –

1. Should I start using unit tests for my new development only?
2. I don’t know why but whenever I start thinking about writing unit tests I suddenly feel “lazy” 🙂
3. I still can’t figure out which are those dark spots where I should not go about test driven development?

Well, first things first. Test Driven Development is hard and requires lots of practice and discipline, so don’t try it at the beginning, you might not even get it. Even if you start writing tests after development, your code base will be in a good shape.

Now Let’s tackle no. 2 first – thanks for being honest about feeling lazy, but I read sometime back that Agile development is “DISCIPLINE”, and there can’t be a more appropriate word to describe that fact. If you are writing unit tests for the code you write, that in itself shows that you are a mature and disciplined developer (person). However highly we rate our programming skills 😉 we are still humans and so we are bound to make mistakes; not only that, our code certainly depends on code which our fellow developers write, and what if they unexpectedly change the behavior of the code (while keeping the external interface same)? How will you know if the code you wrote doesn’t break?

Also, most of us are habituated of doing debugger-driven-development, so much so that a couple days back, I was debugging one of my unit tests 🙂 and one of my colleagues said, stop that! Run the test! So the crux is that debugging is a waste of time, running a unit test is very easy (right click of mouse) if you have tools like Resharper and it definitely saves a lot of time. So think hard, how much of your total development time you spend in the debugger?

Now let’s see some of the philosophical reasons for writing unit tests –

1. Jeremy Miller says that he won’t even look at the code which is not covered with unit tests
2. Ayende says that any code written immediately becomes legacy code if not covered with unit tests
3. Will you buy any car if it was not tested thoroughly in a factory? What if it’s brakes are faulty?
4. Equally importantly, will you sell a car without testing it? (If the answer to this is no, then please do not check in any code until you have written unit tests and do not consider your work done until you have unit tests. Did I mention discipline earlier?)
5. Truly great developers will look at your tests first, to understand the behavior of your code, and the list goes on…

So is that it? No, there are solid technical reasons why unit tests make your code solid –

1. If you don’t have unit tests, you won’t be able to (or find it almost impossible to) refactor your code. If you are not refactoring your code, then you are assuming that you write very good code, which even if it is true in that particular moment, might not remain so after a couple of months (when some of the requirements have changed and you get fresh insights into the code after working on it for a long time). It’s only a couple of months in my current project and I’ve refactored my code atleast twice – introduced some base classes where none existed etc. How do you think was I confident if it didn’t break any existing stuff?

2. Without unit tests, chances are that you are writing tightly coupled code and your code can’t even be unit-tested. I mean how do you know if it can be unit tested? What if you’ve have written all the logic on the button click handler of a form? So a very desirable side effect of a code having unit tests is that it might be less coupled than the one with no unit tests. Now think of this – what does IoC gives you? Less coupling, right? Did you think why? Because if you are using IoC, you must be using classes which implement interfaces. So the benefit is that you can mock those classes instead of using the real implementations.

3. I hope you are aware of mock testing frameworks like Rhino mocks or Moq. There are situations where the SUT (system under test) doesn’t have a state, so you can’t use state testing tools like NUnit. Or while testing the UI, most likely you’ll want to test the interaction of the UI with the presenter, rather than checking the state of the UI. These mocking frameworks make mocking an interface (meaning providing an alternative implementation of your interface with pre-set return values etc.) very easy, so that you can check against those. Most mocking frameworks work on interfaces so if you are not using interfaces heavily you can’t mock anything. Note: you can also do state based testing using Mock frameworks.

4. One other advantage with writing unit tests is that they serve as regression tests i.e. as your code keeps growing, so do your number of unit tests. And after some time, you have a good collection of tests to cover your code base. So think of this – if you write some framework, will anyone want to use it if you haven’t written any unit tests?

5. Lastly, as I mentioned before, if you are writing unit tests, you’ll most probably use interfaces, use some mocking framework and / or write some stub classes e.g. my current code base works off a DB where we have bare minimum rights and there are other accessibility issues. On top of it, we are using messaging heavily (using MassTranit) so when the initial development must’ve started, there would’ve been more such issues impeding development. Hence we have two sets of classes – one actual implementation, which will actually connect to the DB and fetch data and a fake one (where we’ve used the Builder pattern) which will return some hard-coded data. So most of the time we are developing against these fakes, and only when the development is complete, the unit tests are in place, do we check against the actual classes, and this works very well for us. But then think, how much more code we’ve written – stub classes and the unit tests – but doesn’t it show the discipline of the team? And when we hand over the code to the testing team, then we are pretty confident that the code should work.

So long story short – the answer to Q. 1 is NO. If you start writing unit tests for an existing code, you’ll start making it better. Also, maintaining a code base with unit tests is far easier than a code base with none.

Answer to Q. 3 is – I am not sure about this question, but if you are writing tests against a database or to test an actual web service, then beware, those are not unit tests, they are integration tests. So barring these, I believe one can pretty much unit test everything.

I’ve tried my best to answer my friend’s queries and I hope he finds this useful. Please let me know. And btw, once you actually work on a good code base (meaning one having unit tests and having a continuous integration server setup which runs all unit tests when anyone checks-in the code) – you’ll realize that the whole Agile development way is very addictive and you’ll hate to go back to your previous ways of writing un-automated tested code.

Advertisements
Categories: Programming, Unit Testing
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: