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,