Thursday, December 31, 2009

Why Unit test?

This post is a brief talk on the theory of Unit Testing. It is expected that you have a solid understanding of OOP.

Here are some of the pros and cons in practicing TDD (perhaps even to the larger extent of BDD) in OOP. Here a unit is a OO class and is the "system under test." Please excuse the roughness of this post, I just wanted to quickly get some points across.

Pros
  • Covers testing of functionality that may be otherwise hard to test.
  • Typically runs faster than other testing methods.
  • Great for solving bugs and preventing them occurring again. however, it can be troublesome to write such a test which replicates the bug before fixing it. This is especially the case when the bugged code is difficult to unit test (perhaps warranting another form of testing) due to it's structure or how it was written (which in all likelihood was written without testing in mind). (This topic is really large enough for it's own article.)
  • Help to write usable units (classes) and testable code. 
  • What is testable code and why is it important?:
    • Code written in a way that naturally allows easy usage and readability. writing classes from a testing point of view ensures that class is externally usable.
    • A class (or unit) has it's responsibility and behaviour defined upfront (or at least very early) through tests which define the behaviour.
    • Allows the developer to maintain focus on achieving behaviour.
    • Separate concerns of a encapsulating behaviours are easily identifiable through tests. If a test seems to deviate away from the intended behaviour (becomes obvious when you seem to be going down a rabbit hole), than the deviation should be separated and is very likely it's own set of behaviour/responsibility to be tested.

Cons
  • Can require a higher amount of maintenance of tests. Usually coming out when refactoring classes which assume to much responsibility and not separated out into separate usable components.
  • Takes a lot of experience and guidance in writing testable classes. i.e. identifying the signs of when classes take on unwanted behaviour (shortcutting or laziness). A learning developer really should be mentored in TDD.
  • Writing tests for "legacy" code can be very difficult and in the majority of cases requires complete rewrites of a class' structure and how it interacts with others (complex behaviour/algorithms can remain, but should be tested to allow future refactoring).

TBC