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
|
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.


Comments (3)
Feb 05, 2010
Keith Brophy says:
Some good points made here also.Some good points made here also.
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.
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.