Given-When-Then pattern in unit tests
What is Given-When-Then pattern?
We can say that it is a style/template how we can describe some functionality (system behavior) in more readable and natural for human way. It is a part of BDD (Behavior-Driven Development).
In this approach there are three main steps:
Given-When-Then pattern in unit test
Given-When-Then is very popular way to write acceptance test criteria for user stories. But could be also helpful for writing unit test? Of course yes!
The main concept of Given-When-Then pattern is to show process flow in more human way, closer to the way how people imagine the problem. Well written unit test also describes some, mostly very small, part of the system behavior, so we could threat him in the same way like for example acceptance test. It will give us a lot of benefits. Before I start listing benefits let give me to say a few words about Given-When-Then concept in unit test.
Please look at the example:
@Test
public void shouldDeliverCargoToDestination() {
// given
Driver driver = new Driver("Teddy");
Cargo cargo = new Cargo();
Position destinationPosition = new Position("52.229676", "21.012228");
Truck truck = new Truck();
truck.setDriver(driver);
truck.load(cargo);
truck.setDestination(destinationPosition);
// when
truck.driveToDestination();
// then
assertEquals(destinationPosition, truck.getCurrentPosition());
}
As we can see the unit test was divided in the three parts: given, when and then. These parts was marked by comments. In “given” part we should put object definitions, mocks definitions, whole initial assumptions. In “when” part we are putting action/behavior that we want to test. “Then” section is dedicated for verification part. Here we should put our assertions.
Of course occurrence of these three parts is not obligatory. Sometimes “given” part does not exists in test, because we define the whole start data in for example setUp function or other place.
Test like this we can easily “translate” to more readable form:
Scenario: Truck should deliver cargo to destination
Now let me list benefits:
- better readability our test: all test have the same structure, so we are able to understand the meaning of test faster
- ordered structure: all test are divided in three parts, so we are able to find fast for example initial assumptions or assertions even if the test is very complicated
- global pattern: if all our co-workers use this patter we will not have an issue with understand tests created by others
- maintenance: tests that are created it that way will be easier to maintenance
- human thinking way: tests are created in the way how people are thinking
I really do not see any negative side of using Given-When-Then pattern in the unit test.
In my opinion using Given-When-Then pattern in our unit test is very good way to structure and correct readability without extra work.