How do I structure my tests, so that they are understable and focused on the behaviour of the system under test? Given-When-Then and Arrange-Act-Assert are two similar ways of structuring your test cases to make them easier to understand at a glance. This test structure also helps to keep your test focused on a single concern.
Given a state or situation (which you set up in the test)
When I do something or an event happens n
Then I expect an outcome (assert) or interaction between collaborators (mock verify)
Or
Arrange a state or situation (which you set up in the test)
Act to do something or an event happens n
Assert the expected an outcome collaborator interaction
Given-When-Then originates from Behaviour Driven Development. Thinking Given-When-Then helps to think in terms of behaviour rather than internal state. Arrange-Act-Assert is a similar pattern from the eXtreme Programming community.
Example
Here’s an example from the drinks vending machine case we use in our courses, using Ruby this time:
1
2
3
4
5
6
7
8
9
# Given a configured machine
machine = VendingMachine.new
machine.configure(Choice.Cola, Can.Coke);
# When I choose Cola
canOfChoice = machine.deliver(Choice.Cola)
# Then I expect a can of Coke
canOfChoice.should == Can.Coke
Note that we normally don’t put “given/when/then” or “arrange/act/assert”
comments in our test code. We try to keep our tests simple and straightforward,
often extracting setup code into a before
, like we did in the previous
post. We also use test data
builders instead of or in addition to a
setup code. We strive for glanceable tests, where we can see the given, the
when and the then parts rightaway. It acts more as an idiom than a literal
implementation.
Effects
Given-When-Then focuses on behaviour of the system under test: what are we actually trying to do? It prevents our tests from wandering around.
The behaviour focus of Given-When-Then nudges us towards treating the thing under test as a black box - whether it’s a function, object, module, or system. This reduces coupling of tests to implementation. We find Given-When-Then more helpful for this than Act-Arrange-Assert, which is more focused on the internal mechanics of the test.
This idiom also works to formulate acceptance test scenarios, and can draw wider audience into the conversation, e.g. developers, testers, product owners, managers and users.
Further reading
The Arrange-Act-Assert idiom originates from Bill Wake.
We learnt the Given-When-Then way of writing scenarios from Dan North and Chris Matts, who introduced the concept of Behaviour Driven Development (BDD) in the early 2000s.
To learn more about behaviour driven development and writing good scenarios, we recommend the books:
- Specification by Example by Gojko Adzic
- Formulation, Document examples with Given/When/Then by Seb Rose and Gáspár Nagy
This is a post in our series on Test Driven Development.