Expressing tests in a Given When Then style is the core practice of the Behavior Driven Development (BDD) methodology. Details about BDD can be found here.
Writing tests in a GWT style can become tricky when there is no clear understanding / definition of what the actual test and preconditions are.
The Four Phase Test steps:
The setup step puts the system in a specific, well known state.
The exercise step stimulates the system and brings it into a new state. The stimulation is the actual feature under test.
The verification step is nothing else than the comparison between the expected and actual state of the system.
Finally the tear-down step allows the test process to clean after itself.
From a functional (business) point of view the tear-down step does not have any value and this might be the reason why it has been dropped in the GWT style.
GWT is nothing else than the Four Phase without the tear-down step.
The previous definition of the GWT style testing seems to rely on the concept of state of the system. Not all the features in a system rely on the state of the system itself. A natural question then is: is the Given step always necessary when writing GWT tests? The short answer is, of course, NO.
Before proceeding, let’s step back and try to classify tests with a pinch of scientific approach!
Time dependant or stateful tests
All the tests where the history of the system is somehow relevant to determine how the system will react to a user stimulation, fall under this category.
A simple example is, for instance, accessing user details in a web-app protected by authentication.
An authentication failure or the nonexistence of the user will prevent the test from being executed. A successful user authentication is a necessary precondition required for the correct execution of the test.
A GWT test would look like:
- Given the user is successfully authenticated on the system
- When the user clicks on the details button
- Then the name is displayed
- And the last name is displayed
- And the date of birth is displayed
Another example is the attempt of redeeming an expired deal:
- Given I bought a deal
- And the deal is expired
- When I try to redeem the voucher
- Then an error is displayed
A graphic representation of this kind of tests could be:
A – represents the initial status
f – is the user action (the feature under test)
B – represents the final status
If the actual status B matches the expected status then the test completed successfully.
From a math point of view if we think of the user action as a mathematical function, a stateful test satisfies the condition:
B = f(A)
If the resulting status is C instead of the expected B then we found a bug!
Time independent or stateless tests
No matter when it’s tested, but 2+2 it’s always going to be 4. Assuming we have for example a service that performs a mathematical calculation, no matter when the feature is tested, but its results will always (hopefully!) be the same.
Under these circumstances the Given step loses its importance and can be omitted
The only interaction with the system (the actual test) would be enough to perform assertions.
Assuming we’re testing a summation service a typical WT would look like:
- When I sum 5 and 7
- Then the result is 12
Mathematical oriented features are not the only ones belonging to this category. A few more examples are:
- Currency or time conversion
- Picture Resize
- Echo service
Now that some context has been given, let’s proceed with a more accurate definition of the GWT style
A given statement is required when the feature under test requires either
- the system to be in a specific state (eg. user authentication)
- an action to happen before the feature under test can be invoked (eg. ticket bought, the browser has loaded a page)
- time related constraints are met (eg. expiration date)
Sometimes the given step is mistakenly used as initialization or setup step. Some examples could be:
- Prepare data that will be consumed during the When step
- initialize resources (db connection, remote services)
- pre-load data on database
Renaming/rewriting of a Given into a business action
From a business perspective a “Given the database is prepopulated…” is not of any use. At the same time though, these data are fundamental to the correct execution of the test. A good way of resolving this issue is to replace the “Given the database is pre-populated …” with the business action that led to the creation of these data, such as “Given a user is registered on the system”.
Initializing resources like db / rest connections should not be listed in the GWT steps. Most of the current BDD frameworks provide developers with test setup phase where required resources can be initialized.
A when statement represents the feature under test. While in a GWT test there can be multiple given or then, there should be one and only one when.
Then(s) are the verification or assertion steps. It is a good habit to have then(s) steps to assert one single condition per then, and there should not be more than two or three then(s) in a GWT test.
Having too many then(s) is a symptom of testing too much or testing two features at the same time.