Latest Replies

Common terms and definitions from the Journal on efficient software development.

« Test-Driven Development - TDD | Version Control System - VCS »
Saturday
Jun132009

Unit Testing

Unit Testing in software development is a way to quickly verify that smallest blocks of software (units) behave as expected even as the software changes and evolves.

Here's how it works.

Any program could be logically separated into distinct units (in object-oriented programming the smallest unit usually being a class). Developers, while coding these program units, also create tests for them (code blocks containing some assertions and expectations about units). These tests could be used to rapidly verify behavior of the code being tested.

When some other developer introduces new units or changes something in existing units, he can run all the tests available for the program and verify that everything is still operating as expected. Usually running unit tests is a fast operation (less than 30 seconds), so developers are encouraged to do that often.

Here's how unit test suite looks for the Lokad Shared Libraries project (running all 176 tests for the primary assembly takes just 3 seconds):

Unit test suite for Lokad Shared Libraries

If unit tests indicate that something has gone wrong, then the root of these problems could be detected rather quickly (since failing tests point directly to the misbehaving unit).

Unit Testing is extremely important for software development, since delivering projects efficiently without unit testing is nearly impossible. There are software development practices depending on unit testing:

  • Test-Driven Development (TDD) - software design method requiring developers to write tests before writing code (this may sound strange, but it works)
  • Continuous Integration - software development practice that allows to isolate some bugs in time by automatically running unit tests after each change to the code.

There are some additional benefits of unit testing:

  • it facilitates change - developers are encouraged to refactor and change code, since they have a way to rapidly verify that program units still behave as expected.
  • a good unit test is living documentation for the code, since it describes how the code is expected to behave;
  • unit test is a good way to communicate over issues in the code and distribute work between multiple developers.

It is important to keep in mind, that unit tests only facilitate change by testing individual code units. They do not guarantee that the entire program will be free from bugs.

Here's the simplest unit test in C#, using NUnit framework:

[TestFixture]
public class CalculatorTests
{

  [Test, ExpectedException(typeof(DivideByZeroException))]
  public void Divide_by_zero_should_throw_exception()
  {
    new Calculator().Divide(1, 0);
  }

  [Test]
  public void Adding_actually_works()
  {
    var result = new Calculator().Add(1, 15);
    Assert.AreEqual(16, result);
  }
}

As you can see, a unit test is simply a class that contains methods checking behavior of some Calculator class. This test class is sometimes also called test fixture or test suite. In this snippet above test methods are decorated with a special attributes that are used by NUnit framework to recognize them, run as needed (i.e.: within an automated build) and print results.

Although this unit test suite may look extremely simple, it does not have to stop there. Here are some advanced usage scenarios that simplify development of complex enterprise applications:

  • setup a temporary database before unit tests start up and then check all data access routines against this sample database;
  • have a test suite that executes every hour against methods in your web services, verifying that they are alive and processing data properly.
  • use non-deterministic reproducible tests that verify behavior of your class in various unexpected situations, reporting back when something goes wrong;
  • use unit testing framework to write code quality tests, that check and enforce some guidelines (i.e.: every controller class should be immutable and have name ending with Controller).

Related Links:

This article is a part of Software Development Body of Knowledge ABC series. You can subscribe to RSS feed to stay updated.

Reader Comments (3)

Hi Rinat,

Again, you posted good stuff.

You wrote quite interesting articles about lambdas expressions, but the comments for those articles are closed.
As those articles are very informative, maybe is better to allow comments on them.

September 30, 2009 | Unregistered Commenterdann

Thanks for the feedback!

Articles usually are locked for comments automatically within 3 months to reduce the amount of spam. But it is a pleasure to unlock any, should the community consider them worth to be commented ))

October 5, 2009 | Registered CommenterRinat Abdullin

Nice article, I was looking for these kind of information.
Please continue writing....

Comments for this entry have been disabled. Additional comments may not be added to this entry at this time.