Access Keys:
Skip to content (Access Key - 0)

Navigate your Test Drive

I have always approached testing (unit/integration/functional) as a necessary evil for good development projects. However, upon recent reflection, I see that this opinion was based on the fact that I found it difficult to write good tests, and even harder to maintain them. When returning to complex tests, it would take quite some time to understand and recapture the intentions I had originally codified in the tests.

Lost

Previously, my style of test writing would involve creating a test with various configuration calls, the actual action I wanted to test, followed by some assertions that the the code had generated results as expected. All of these aspects were in one test method, without any clear delineation as to the purpose of each line of code. While the test name was descriptive, the actual working of the test was not always easily understood.

Navigate your tests

However, by employing the simple technique of breaking tests into distinct concerns, I have found test writing has become easier and has also made tests easier to maintain. Following a Behaviour Driven Design style of the Given-When-Then pattern, each aspect of a test can be codified separately and remove clutter from the test itself.

Like a navigation system, it allows you define these details:

Test Navigation
  • Given - where are you starting from - what elements are required for the test
  • When - how you want to get there - normally the action/method under test
  • Then - where you expect to arrive - verification of the results

This paradigm helps me understand what I am trying to test and how I should test it. For example, the class GroupManager may lead to the test

  • given there are no groups in the group list
  • when I add a group
  • then there is one group in the group list

Further, each of the concerns should be addressed in individual, well-named methods. The actual implementation clutter of how a group is added or how the verification is achieved is removed from the test itself, improving readability and highlighting the intentions of the test immediately - e.g.:

@Test
public void testGroupIsAddedCorrectly() {
   givenThereAreNoGroups();
   whenOneGroupIsAdded();
   thenThereIsOneGroupInList();
}

This style also lends itself to code reuse - a lot of tests will be able to use the same given method, or will verify similar assertions in the when methods.

Turn Right At the Next Assertion

In recent months, I feel that I have really begun to reap the benefits of testing. The ability to refactor any code (with good test coverage) with confidence that the system is still operating as expected is a prime benefit. I tread very lightly where code does not have good coverage and feel constrained that I cannot change code easily.

Having employed this technique for testing, I have found that my code coverage (and hopefully, my test quality) has greatly increased.

Toggle Sidebar

Author

Archives

  1. 2010
    1. February
    2. January
  2. 2009
    1. December
    2. November
    3. July
    4. April
    5. February
  3. 2008
    1. November

Blogroll

  1. Feb 05, 2010

    Keith Brophy says:

    Some good points made here also.

    Some good points made here also.

  2. Feb 05, 2010

    Jonathan Mort says:

    Good post What I like about given/then/when is the way it really shows the int...

    Good post

    What I like about given/then/when is the way it really shows the intention of each test and how they read like a story. Some of the functional tests could even be shown to a non-programmer customer and they would understand what the system is trying to test.

  3. Feb 05, 2010

    Emma Rush says:

    Great post Keith, you have a refreshingly easy to read & understand style of...

    Great post Keith, you have a refreshingly easy to read & understand style of writing.

Adaptavist Theme Builder Powered by Atlassian Confluence