Monday, July 6, 2009

Real programmers write unit tests (part 1)

Among the good practices that we have put in place at work the one that has been consistently rated the most beneficial by the programmers using it is writing unit tests. It has a beneficial impact on both the quality of the code, the number of bugs detected in the system tests and the schedule. Unit tests make development more deterministic and less stressful.

The tools

We write most of our code in Java so we use JUnit. We use version 1.4 and we use the Hamcrest matchers. We also use a few extensions:

  • Fest for testing GUI

  • DbUnit for testing database related code.

  • We do not yet use mock libraries. Because we write a lot of mathematical algorithm, the Junit 1.4 parametric tests is a great tool for us. It is very productive.
    We use Ant to run the unit tests as part of the daily build. The build is interrupted if there is a test failure. No release image is generated if a unit test fails.
    Recently I did some development in C#. I used NUnit for unit tests on that project.

    The process

    We do not yet use TDD but we do test early. Also, for me, the emphasis as shifted recently from testing methods to testing scenarios. I will probably keep using a mix of method oriented and scenario oriented tests because I find both type to be useful. Method oriented tests for simple more technical classes and scenario oriented tests for the more complex business related classes. The details of the process depends on the type of development involved: maintenance of legacy applications and development of new applications and modules use a slightly different approach.
    Development of new application and modules gets the most benefit from unit tests. It is easier to apply good design and coding practices with new code and those facilitate unit testing. Design principles and coding practices that are beneficial to unit tests includes:

  • Small highly cohesive classes

  • Those are easier to unit test

  • Defining interfaces and coding to them

  • This makes unit testing easier because it facilitates writing mock classes and stubs. I mentioned earlier that we do not yet use mock libraries. However, we do write mock classes. Having well defined interfaces makes this process easier.

  • Loose coupling

  • Keeping an eye on coupling is really important. I use a metrics tool for that and I refactor early if needed. High Efferent coupling can make unit tests very difficult.

    Even on new projects you will sometimes have to work with code that was not developed with unit tests in mind. For example, third party libraries and classes can be a source of complications. In my next post I will talk about writing unit tests in more details. I will show some techniques that you can use when working with non unit tests friendly code and legacy applications.

    No comments:

    Post a Comment