Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Derik Whittaker

Thoughts on Software Development, .Net, OOP, Design Patterns and all things cool



Why I believe IN and WRITE unit tests

In my last post I think I struck a cord with some people in my post 'Unit tests taking too much time'.  My intent was NOT to sound like an elitist Agilist or any else of that nature.  My intent was simply to put a post out there about the misperception (in my opinion) about how writing unit tests take too much time.

I thought I would put my 'retort' on why I believe in and write unit tests.

Allows ME to write better code

I believe that when I truly follow TDD practices my code comes out simpler.  I have also found, that my code tends to follow YAGNI more so then when I don't follow TDD practices.

Here is an example from my past experience.  On a prior project I needed to build a 'search engine' into our app (this was not an actual search engine, more like a hunt path engine).  When I first started out writing code I started out by creating all these classes and logic that I thought I would need.  After about 3-4 hours of coding I was dead in the water.  I was not able to solve my problem in a simple manner and I was frustrated.  I decided to take a step back and start over. 

This time though I started out by writing test to mimic what I actually needed.  I continued to follow the principles of TDD (btw, TDD is more then just about writing tests), within an hour or so I had my solution pretty much good to go.  All those classes and methods I THOUGHT I would need I did NOT.  I was able to scrap about 50% of the code/classes that I thought I needed.  And guess what, now I have a test suit to test my new code.

Allows ME to find more bugs during the development process

It has been my experience that I find more bugs while writing tests.  This is due to the fact that I not only follow TDD, but I also do my best to implement the Fail Fast Principle.  When I am writing my tests I have the ability to create tests that easily walk though the different pathways of my code (I attempt to hit 100% code coverage as well).  If I were not writing tests I would have to do this via the application, and this is much more painful and it less likely that I would actually do it.

By writing my tests and testing my code during the development process I know that I have reduced my bug count significantly.

Makes ME feel more comfortable making changes

This is the beauty of TDD, I am not afraid to make any critical changes to my code because I KNOW that I have tests to verify if I screwed anything up. 

Have you ever run across some code that 'you were scared' to change?  If you had tests for that code I bet you would a WHOLE LOT LESS scared to make any changes.  I know that I am.

A case in point for this is as follows.  On a prior project a consultant I was working with needed to make changes to some 'smelly' logic.  This just happened to be a week or so before a scheduled release.  Beacuse he had NO confidence that the changes he would make would NOT break the application, he convinced the business to NOT make the changes.  I bet you a dollar that had there been unit tests he would have been much more willing to make the changes.  In this case the fact of NOT having tests may have caused the business to lose out on features it needed.

Improves MY code

Because following TDD practices forces you to write your failing code before your passing code, I tend to implement my intent much cleaner and simpler.  I also know that because I am writing tests along the way my code is solid.

Allows ME to better convey intent

I know that tests are not a substitution for quality comments that convey intent, but they sure are the next best thing.  It is really nice to be able to point someone towards a suite of tests to 'demo' how to use a component.

A case in point for this is as follows.  A few weeks ago at work I wrote an API to allow the querying of some data via our imaging system at work.  Turns out that an outside party needed to use this API for integration into on of our 3rd party applications.  When he came to me asking for 'how do I use this', I simply emailed him my suite of tests.  In this suite I had pretty much any conceivable use for the API.  To date the vendor has not asked me how to implement the API.

Allows MY tests to be automated and rerunable

This is a nice side effect of having tests.  Because we use both NUnit and CruiseControl I can run my tests on every check in.  This is cool because now I (and the team) know if changes I made breaks some other part of the system.  I would rather know now then before QA hits it. 

The above are simply my opinion, if you don't share the same opinions, let me know.

Till next time,



Comments

Derik Whittaker said:

@Joe,

Yes, i would still suggest TDD for an app that is 90% CRUD.  I would suggest witting test that actually test the CRUD layer.

Here is what i would suggest.  

1) Have a test that inserts data

2) Have a test that performs a select on your newly created data

3) Have a test that performs an update on your data

4) Finally have a test that performs a delete on your data.

Of course you are doing all your data access via procs, but you still have to build the command and send it though.  

On more then one occasion these types of tests have found bugs for me.  The CRUD may seem simple and too easy for bugs to appear, but they can.

One last thing.  Most apps that appear to be 90% CRUD turn out to be more like 60% CRUD.  

Hope this answers your question.

# October 1, 2007 10:09 PM

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# October 1, 2007 11:46 PM

Omer Rauchwerger said:

Derik,

I couldn't agree more!

Check out my related post from earlier this year - blog.rauchy.net/.../why-tdd-works-for-me.html

-- rauchy.

# October 1, 2007 11:47 PM

Christopher Bennage said:

Good post.

# October 1, 2007 11:48 PM

Scott Bateman said:

Thanks for the down-to-earth post.  Solid points that make it easy to see the multi-faceted benefits of a continuously tested development approach.

# October 1, 2007 11:58 PM

mark said:

This post was MUCH better then your last one.  At least in this one you provide something to support your arguments and you managed to avoid implying that anyone who didn't agree was ignorant.

So my old question still stands however.  Since your obviously very experienced with TDD, what benefit is there to an established and experienced team who's product already has a very low fault rate, is easy to modify and/or add new features to it, and a customer who is extremely happy with it?  Given that, would you not agree that the excessive time that would be spent writing unit tests is better spent adding features requested by the customer?

# October 2, 2007 7:28 PM

Derik Whittaker said:

@Mark,

I will agree that backing in unit tests into an application that is ‘stable’ and deployed is very difficult and can be time consuming.  One thing I have done in the past is to not attempt to tests existing functionality or old code.  Start writing tests with your new code.  This is a great way to learn TDD, like they say you have to crawl before you walk, walk before you jog and jog before you run.

I have been in situations like this in the past and have only tested new code or features.  Once you are comfortable with this, then maybe you start writing tests for existing code ONLY when you have to make changes with it.

Hope this helps

# October 2, 2007 8:04 PM

Johan said:

Derik,

How do you implement the Fail Fast Principle? Do you also use asserts in the code to be tested.

# October 6, 2007 3:30 PM

Johan said:

Hi Derik,

Just found you're article on Fail Fast :-)

devlicio.us/.../fail-fast-principle.aspx.

# October 6, 2007 3:46 PM

Nikola Malovic said:

Nice post!

I think there's just a few arguments to be added on your list regarding enhancing various aspects of the team work  and that could be then a nice list of arguments which should be used selling TDD to non TDD teams :)

# October 16, 2007 1:34 PM

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# October 27, 2007 12:16 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Derik Whittaker

Derik is a .Net Developer/Architect specializing in WinForms working out the northern suburbs of Chicago. He is also believer and advocate for Agile development including SCRUM, TDD, CI, etc.

When Derik is not writing code he can be found spending time with his wife and young son, climbing on his bouldering wall, watching sports (mostly baseball), and generally vegging out. Check out Devlicio.us!

Our Sponsors

Proudly Partnered With


This Blog

Syndication

News