DEV Community

Cover image for GivenWhenThen Pattern
smotastic
smotastic

Posted on

GivenWhenThen Pattern

There are lots of different ways on how to write, organize and structure your tests.
One of these patterns is Given-When-Then.

The term was developed as part of the Behavior-Driven Development process (https://dannorth.net/introducing-bdd/).
In general it describes a pattern on how to write, and describe a desired scenario.

  • Given describes the initial scenario
  • When describes the event that happens, which will change the scenario
  • Then describes the expected outcome of the scenario after the event happened

Example Scenario

Defining a scenario using this pattern could look like this.

Scenario: A user wants to buy a book from a well known e-commerce platform.

Given the user owns no books from this platform.
When the user orders and receives the ordered book from the platform.
Then the user should have one book in his possession.
Enter fullscreen mode Exit fullscreen mode

Test-Scenarios in Java

When using this pattern in the world of Software-Development-Testing, it is important to agree on conventions made by the team. This ensures the consistency of all written tests.

Consistency is a big advantage in helping to quickly understand, and also learn how certain usecases are supposed to work.
Imagine a new developer joins the team. Merely by reading the tests he will gain knowledge of how something should, and even might work in the application.

In general, these conventions should be defined and agreed upon by the team. In the case of the Given-When-Then pattern I always pay attention to two factors.

  • Structuring the testmethod
  • Naming the testmethod

Structure of the Testmethod

As the pattern says, there are always three parts in any given scenario (or usecase),
and the testmethod can be structured in exactly these three parts.

First is always the given part. The initial values for the scenario. This is basically the setup for any test.

Second the when part. This is the execution of the desired method that is to be tested, or as specified before, the event that happens.

Third the then part. The verification, or assertions of the values after the event happened.

Putting this structure into a test, which tests the functionality to buy a book, could look something like this.

// given
String shouldBuyer = "hanswurst@test.com";
Long anyBookId = 1L;

// when
UserBook actual = sut.buyBook(shouldBuyer, anyBookId);

// then
assertThat("the actual owner of the book, should be the buyer", 
    actual.getBuyer(), equalTo(shouldBuyer));
Enter fullscreen mode Exit fullscreen mode

Name of the Testmethod

Normally I prefer short self-documenting names for methods.
For tests though, I cut the "short" from this preference.

A test should always say what it is trying to test. Of course, you could do this by documenting it with some Javadoc, or you could just name the test the way you would normally document it.

Applying the Given-When-Then pattern to this definition, the name for our book-buying test could look something like this.

@Test
public void givenValidUserNameAndBookId_whenBuyBook_thenUserShouldOwnNewBook() {
    ...
}
Enter fullscreen mode Exit fullscreen mode

If you ever googled the topic of long method names, you probably know that there are a lot of discussions on this topic, and they are for a good reason.

Long names can imply a complex implementation for a method.
And if you don't think you can shorten the name of the method, without losing information that the developer might require to understand the method, it's probably true that it's too complex.

For tests on the other hand, this argument doesn't apply. We are just testing an implementation, and not implementing some logic. The tests are also not called from anywhere else but the test runner, so we are not cluttering our code with long method calls.

Conclusion

The Given-When-Then pattern can be used to define any given test scenario.
Implementing it in the world of Software-Development can be done by following conventions agreed upon by the team.
That is true for other patterns too.

So I would like to conclude by saying whatever Pattern, Libraries or whatever Framework your team chooses to use,
the most important thing is that your team agrees on what they use, so you can ensure a consistent way of developing and testing your software.
This will help the team in the long run to further develop features, maintain the application and keep understanding what in the world is happening here.

Read more

Top comments (0)