Why Unit Tests Matter and How They Will Actually Save You Time

Note:  The point of the post is to explain why unit tests can actually save you time in the long run even if you or your boss don't currently use or believe in them.  It's not my goal to go into some silly religious discussion about why unit tests should or should not be used in a project.  There are plenty of forums out there for arguing over various technical concepts and methodologies if you have the time to waste.

Many different philosophies have been proposed that offer solutions for writing quality code.  As a result, two people will generally give two different answers if you question them about the best way to write quality code.  Regardless of your views on writing quality code, testing has to fit into the picture at some point.  We could argue over exactly where testing fits into a project but I don't think anyone would argue that testing can be skipped (and if you're one of those people you can save yourself some time and stop reading now :-)).

I've never been one of those "letter of the law" people when it comes to just about anything and that applies to concepts like testing code as well.  I believe balance has to be reached regardless of what you're doing.  There is such a thing as going "overboard" when it comes to software development, studying for a test at school, training for sports or many other things.  However, everyone's definition of "overboard" differs and I respect that so I'll move on to the heart of the matter which is unit testing and how it can benefit your projects even if you don't agree with the "letter of the law" people out there.

If you're new to unit testing, I'll sum up the general concept quickly:  Write tests followed by code to satisfy those tests.  That one statement doesn't do unit testing justice, but hopefully you get the basic idea.  Do I always write my tests first along with the application's general stub code?  Simple answer is "I try to".  I try to follow best practices but in reality it doesn't always work out exactly how I want. 

Regardless of your view on the overall process, unit tests can still provide significant benefits in my opinion even if you write them later in the development process.  The "letter of the law" people out there probably consider that to be completely wrong, but I try hard to keep in mind that everyone and every project has different skill levels, needs and constraints.  Whether you write your unit tests at the beginning, in the middle or even at the end of a project (pushing them off until the end is NOT recommended and your hand should be slapped with a ruler if you do that :-)), they can still provide you many benefits.

There are numerous Websites dedicated to the topic of unit tests.  Wikipedia provides a nice overview here. A few of the benefits unit tests bring to the table include:

  • Forces more thorough consideration of an application's design
  • Simplifies code integration
  • Catches bugs more quickly in the development process
  • Simplifies maintenance
  • Provides visual test results
  • Provides a testing history
  • Makes you feel better about the stability of your application (assuming you have good code coverage)
  • Many more....

For some people writing unit tests before writing application code (more than just stub code) is absolutely required for writing good software.  I agree with that stance overall since if you build testing into a project from the beginning then you should definitely have higher quality code in the end if you stick with it and ensure that you've achieved good code coverage with your tests.  However, I've also been on projects where writing all of the unit tests up front simply wasn't going to happen due to the time constraints (which are sometimes ridiculously out of touch with reality) placed on a project.  Regardless of your situation, unit tests can still help you in the short-term and long-term. 

Here are a few reasons you should consider using them if you're not already.  I've found that they actually save time in the long run if you spend a little time up front.

  • How many times have you written test harness code to test a particular feature?  A lot of people whip up a quick console project (or multiple console projects) to do this type of thing.  By using unit tests you can save yourself the time of writing test harnesses since unit test frameworks do that for you plus have the ability to run the tests anytime and see their status (green light, red light) aggregated together in one nice report.  If you've never worked with unit tests before here's an example of what tests results can look like (this one is generated by Visual Studio 2008):

image

  • How many times have you or someone else asked, "How will this one quick change affect the application?".  For many applications a "small" or "quick" change is made without knowing the impact on the overall application.  It's kind of a guessing game for some people. You think it's a simple change only to realize that the one "simple" change affected many other things as well that you or someone else may have forgotten about.  If unit tests were in place (assuming good code coverage) you could make the change, run the tests and instantly know how it affects things.  It's like having a crystal ball in some ways since by having unit tests you can more accurately predict future changes and the impact they'll have.
  • How do you know if code contributed from multiple people on a project integrates well?   If unit tests were in place you could test their code along with your code and see if things play nicely together.  This of course assumes that everyone is writing unit tests for the code.
  • How do you get test data into and out of a database?  While you certainly don't need unit tests for this, startup and cleanup unit test methods can be used to automatically populate a DB with test data (with a little work on your part) as tests are run so that your functional tests can be run against real data.  People normally write some code to insert test data anyway (or use 3rd party products to do it like some from RedGate Software) so why not do it as part of your testing process? 
  • How many times have you been asked for a status report on an application?  If things are organized really well you'll probably have a project plan in place that can be updated.  In other cases, sending the results of unit tests (sending an image like the one above) does wonders to help people see where things stand on a project.
  • How many times have you had to provide production support for an application someone else wrote?  Debugging someone else's code is never a fun task especially if documentation is light or non-existent.  Imagine inheriting a project that already has good unit tests in place though!  You can add your tests (if needed), make the updates or bug fixes and then run all of the tests to see how things look.  It's much better than guessing if an application works properly or not especially if you don't know much about the application to start. Plus, unit tests provide a built-in type of documentation since you know what the key methods are in the application that you need to understand and worry about.

To sum things up, I'm a big fan of unit tests simple because I end up writing test harness programs at some point anyway, need to debug a production application or am forced into a situation where someone wants to make that one "simple" change in an application and I don't know the true impact.  By using test frameworks such as Visual Studio, nUnit, xUnit.net, mbUnit, etc. (I personally use the features found in Visual Studio)  I save myself the time of getting test data into the database, writing test harnesses, maintaining an application, plus much more.  By writing unit tests are you going to catch all of the bugs?  Obviously not...but you'll be well ahead of where you would have been without them.

Don't take my word for it though, start creating a few unit tests for an application you're already working on (even if the tests are created after the fact in this scenario) and you'll see how nice it is to see green lights as your tests pass or red lights when you need to fix something you wouldn't have caught otherwise.  It sure beats pushing off all testing to your end users and wasting their time reporting bugs that you could have dealt with much earlier in the development process. 

If you're interested in getting started with the overall concept of unit tests some nice starter articles can be found here and here.  I'm sure there are other "How many times have you...." type questions where unit tests can help and even save time.  If you have additional suggestions please add a comment.

comments powered by Disqus

4 Comments

  • The more I hear about unit testing the more doubts I have. I've done some big projects and, while sometimes unit testing was extremelly useful (to test and ensure data structures corectness for example) I found one drawback for some cases which makes testdriven development impossible to follow. What if writting the test takes as much time as writting the actual code?

    For example, some time ago I was developing an expert system which would evaluate some rules against the database and take some actions if they got raised. The application was multithreaded to improve perfomance and based on the RETE algorithm. In such conditions writting a test could take days, and get so complex that maybe you would need to write a test for the test... The interaction between the threads could no be easily tested. Being an expert system it was heavily dependant on state (refering to the data present in the database) and, as the data and the number of rules raise it was even difficultier to assert if any given test was succeding or it wasn't.

    In conclussion, I've found that, for really complex projects, where the test cannot be asserted as just "Aseert(cond="allok")" automated unit testing is not that useful. I think it is very important, specially if you're developing a framework as it has more predictable use cases, but I'm still waiting to see a real life, big complex application, example.

  • Jorge,

    Thanks for taking the time to discuss some situations where unit tests end up being more work than they're potentially worth. I definitely would agree that they're not always a perfect fit for every situation. I use them mainly for testing business rules, database access, etc.....where a fairly straightforward assertion can be created. I talked about "balance" some in the post and I think you've touched upon a situation where unit tests may potentially be going "overboard" especially if you'd need a test for the test. :-) I'm OK with taking time upfront for writing tests since they almost always save me time in the long run, but if it's literally taking more time to write the test(s) than the actual project code then that's a little harder to justify. But, as mentioned, I'm NOT a "write unit tests for everything" type of guy. Every project has to find a good balance.

  • rrobbins,

    There is some work upfront so I won't pretend it's all child's play, but with tools like Visual Studio the test stub code is created for you. Once you get a nice pattern going in a test for inserting data in the test startup method, testing the data in the actual test method and then cleaning it up in the test cleanup method you may actually be surprised how quickly you can write tests. Once you get the hang of it some tests can be written very quickly, often times in minutes ((and I'm thinking more of business rules or data access tests). I thought a lot along the lines of what you mention initially until I tried it. Now, if I need to tweak some code that's already been completed I can run the tests quickly to see the impact which is nice. Plus, I always had to test with some fake data anyway at some point of the project and my unit tests do that too. The work that I put in the unit tests typically was done at some point in a much less organized manner anyway (creating test harnesses, testing with data, etc.) so I found that just deciding to do that work in a more organized manner with unit tests was worth it....to me anyway. :-)

    I don't expect anyone to use unit tests as a result of reading my blog post. I mainly wanted to write about why I personally think they're worth it in the long run. Everyone has they're own way of doing things of course.

  • In 2000 the development team I was working on adopted TDD. Initially (for the first 6 months or so) we saw little productivity gain. We saw HUGE gains in productivity as the test suites became entrenched in the solution. Taking the reduced amount of time fixing defects in test and production and the increased agility that permitted for faster refactoring and feature delivery there was upward of a 70% gain in team productivity. TDD should be a part of any professional development shop.

Comments have been disabled for this content.