Monday, January 30, 2006

HOWTO write unit tests

I was working on a project, where the client had requested to follow the test driven development (TDD) methodology while working on his project. Before this I personally had read a lot about TDD and unit test in particular, but I had never engaged it a real project.

Some very common questions that you will have in this case is:
* What functionality should I test?
* Are my tests relevant to the business requirement?
* How should I structure my unit tests so that I know which ones to run when I make a specific change?
* How many unit tests are "good enough"?
* How should I design my code so that it is liable for easy unit testing?

One of the very good consequences of TDD is that each developer starts thinking a little bit like a software tester. We all know that developers develop to run, while testers run to break. Well, if developer invests some time to gain a more comprehensive understanding in the problem that (s)he has to implement, then chances are that (s)he will produce less bugs. And this is one of the main tenets of TDD. By developing test cases, developers tend to gain a more versatile understanding over the problem domain they have to implement and thus their code is prone to less bugs. I totally agree that this is just a theory, and basically it depends on what unit tests the developer creates, what is the code coverage of those tests, how often are the tests run and of course - are the tests actually relevant. A good place to start learning what are the most basic requirements for efficient test cases, visit the article "Write Maintainable Unit Tests That Will Save You Time And Tears" (link).

One of the biggest challenges that I had so far in my experience was to design my code so that it is easier to be unit tested. It really depends on the programming language that you use as well as the platform that you are using. My experience so far is with Microsoft .NET, where the unit testing framework which is most used is NUnit. So when it comes to design, we had to design our applications that in one hand they are easily to be tested, but on the other side the testing code is somehow out-of-the-box. Therefore, we decided to implement the business logic in separate class libraries (.DLLs), which exposed the main business classes. This has the following benefits:
1. Class libraries allows to be easily reused - thus, we wanted to use a single assembly for multiple places within our system, we were able to to this
2. Class libraries are easier to be tested - what we did was to create a "bootstrapping" code which just represented the specific unit tests on each single class / method. Thus, we had very well separation among unit testing, business logic and presentation.

Here is an article that is something like a quickstart for test driven development in C# - click here.

No comments:

Post a Comment