Unit Testing

by David Kiff 10. July 2009 19:58

Unit testing is the testing of a small isolated unit, typically a method. It is written to ensure the code behaves in the way it is intended, drives the architecture and ensures the code meets its requirements.

By isolated, it is meant there should be no interaction between dependent classes and no other systems should be interacted with (such as databases, file system, web services etc). The reason for this is to thoroughly test the core logic of the unit, rather the connectivity to the database for example. The code is isolated by injecting the dependencies into the class, which provides the capability to inject mock instances of the dependency for unit testing. It is important to remember a class should have a single responsibility. When the class starts to take on another responsibility is it might be time to refractor that into a new class and inject it into the dependent class.

Every Unit Test written should be independent of other tests, in other words, they could be run in any order without adversely affecting other tests.

Unit testing is not solely around testing the code. It is proposed that a test-first approach is adopted because it forces the developer to thoroughly think about what they want to achieve, before rushing straight in. The test-first approach will also drive out the architectural decisions of the application in a way that promotes loose coupling. When implementing the code to pass the test, the developer should do the simplest implementation possible to pass the test. This ensures the code is as straightforward as possible, without the typical YAGNI (“You Aren’t Gonna Need It”, see http://c2.com/xp/YouArentGonnaNeedIt.html) mentality that is often accounted for and burdens development.

A suite of well written unit tests give the developer confidence to maintain and change the application. If a mistake has been made, there is a fair chance this defect will be highlighted when the suite of Unit Tests are run. The tests provide a set of low level regression tests.

When a defect is found, a test can be written to reproduce the problem. When the test is failing, the fix can be put in place and the test should pass. This can give the developer the confidence their proposed fix actually works.

All code with logic must be tested. There is arguably little value in unit testing a DTO for example, because it is just a number of properties and no logic. Likewise the .NET framework should be fully trusted and does not need to be tested. This includes “wrapper classes” that directly interact with the framework.

The main problem faced when documenting how a system behaves is the maintenance of the document itself. Often these documents become out of date and no longer useful. Unit tests can provide helpful, living documentation on how the system should behave. If the unit test is given a descriptive name and is setup in a consistent manor (see Code Sample 1), developers should be able to quickly grasp the codes intentions and expected behaviour.

[TestMethod]
public void MethodName_ShouldPerformSomeAction()
{
//DATA SETUP
//EXPECTATIONS
//CALL
//ASSERTIONS
}

Code Sample 1: Example of a Unit Test Setup

Our chosen testing framework is MSTest due to its ease of use and integration within Visual Studio. Most of the mocking frameworks work in similar ways. The mocking framework of choice is RhinoMocks, mainly because it does not use literal strings when setting up expectations (something that NMock2 uses). This provides us with good refactoring support and a reduced chance of making hard to spot mistakes. For more information on RhinoMocks please visit http://ayende.com/projects/rhino-mocks.aspx.

From past experience, Unit Tests will not be maintained unless they are run often. The easiest way to ensure they are run frequently is to integrate them into the continuous integration system. This helps to identify potential defects when someone checks-in some broken code and hopefully maintains a healthy codebase.

Tags:

Test-Driven-Development

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading