Unit Testing – luxury or necessity?


I was reading a blog recently about this and it got me thinking about unit testing and how some of the issues mentioned are the ones that I personally see us facing today as part of the way we code. It got me thinking, so I ended up writing a few common Q+As that I’ve heard for a reason why we don’t always unit test.

I’m a big fan of unit testing (and particularly test-driven development) so you can imagine which way this post is going to go, but anyway… perhaps look at this as a way to convince your PM/ team lead next time you are starting a project and want to include unit testing in it (or just do what I’ve done for the past couple of years i.e. just do it without asking 🙂

We haven’t got the time / budget for unit testing!

My answer to this is: when you estimate how long it will take you to code a feature, do you ask whether you should do for any of the following: –

  • Analysis
  • Design
  • Developing the solution
  • Commenting your code
  • Manually testing it
  • Running it by a couple of other people as a sanity check
  • Getting it peer reviewed

Do you just include the above areas as part of your estimate? If so – why not just include unit testing as another “facet” of your implementation steps? What I’ve sometimes been doing recently on a project is adding separate tasks under scenarios for “write unit tests”. In a sense, this shouldn’t be necessary if you’re doing TDD – but it’s a decent way to start doing unit tests if you’ve not done it before.

When I wrote earlier on that I simply do unit testing now without asking, there was a smiley next to it, but in reality it’s not really a joke – what I was talking about was more that unit testing should be a “standard” part of our coding practices, as much as manual testing or comments etc. should be – and not seen as a “luxury” that we can or can’t afford to include in our budget.

Unit testing takes too long for the benefit that it gives!

Talking from personal experience here, all I can say to this is that it’s blatantly not true. I would say that to code a given feature (having been using TDD for a year or so now) it takes maybe 5-10% more time to develop with unit tests than without them, for the FIRST VERSION OF THAT FEATURE.

Once I start enhancing that feature – changing its scope, or making it more complicated, the time taken to develop it drastically comes down in comparison to the non-unit test approach. This is because you instantly know when you’ve broken your code by breaking existing unit tests.

What are the other benefits of TDD?
  • You feel more comfortable refactoring and redesigning your code because you have tests that validate that the refactoring hasn’t broken the tests.
  • When the application goes into support, whoever takes over the application will know immediately if they’ve broken something as part of any changes that they are making.
  • Unit tests can become a form of documentation i.e. demonstrating how to interact with a class, expected responses to method calls etc.
  • It encourages and enables you to keep your code as clean as possible. Once you have unit tests, there’s no excuse for the “quick fix” / “hard coded” enhancement, because your fear of accidentally breaking existing code disappears with unit tests.
  • You can use this as a way to demonstrate to management and / or even clients that your application has been thoroughly tested e.g. rather than “we have spent five days system testing it”, you can say “we have spent five days system testing it, in addition to the 657 automated tests we have run every day”.
  • VS tools can make your life much easier e.g. code coverage and metrics.

Unit testing UI-based / event-driven applications is impossible!

There are two ways (that I am aware of) around this sort of issue: –

  • Write UI-driven tests e.g. put methods on your forms like “SetDob” which accepts a value and simulates a user action. Your unit tests will create a form and show it, then call such methods to test what happens.
  • My preferred option is to avoid that, and instead ensure that all your business logic is not in your form, and either in your presenter (with Smart Client you get this for free), or elsewhere e.g. business logic layer / data access layer etc. You quickly learn to make your classes as decoupled as possible from one another in order to make testing them as simple as can be. You can use mocks to emulate the UI tier; frameworks like Rhino make this very, very easy to do.

It’s too hard to learn how to do it!

The first time that you use test driven development, you will probably spend a day or so getting quite a bit less done than normal – but once you’re used to it, you’ll no longer look as unit tests as an “overhead” but simply a natural part of your development lifecycle.

Summary

I guess what I hope is that you at least try unit testing and / or TDD once before ruling it out as a “luxury”. It’s not a “fix all” answer to bugs – unit testing is only as good as the tests that you write – but I believe that they provide a massive (and I really mean that) benefit for us as developers in writing fault-tolerant code.

Advertisements

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