Gherkin - How to set up something that’s not supposed to exist?
This is my first foray into the first post of an series of challenges on the Specflow website. The point is, what do you do when you’re setting up a user that does not yet exist?
I’ve pasted the text taken from the link above:
Given user John does not exist
When John tries to register
Then the registration is successful
Given user John exists
When John tries to register
Then the registration fails
You can write scenarios this way to ensure that the system creates unique accounts. But could it be clearer? Can you see how it can be vague? For example, what does the name ‘John’ express? The first name or the email?
My thoughts
- It’s vague
- The test data problem
- One scenario or two?
It’s vague
To begin, the question itself already reveals one of the answers. What does ‘John’ mean and how do we determine an account is a duplicate? The scenarios are not specific enough developed by a coder. That is the first step, map out all the possible critical paths. A few come to mind:
- Duplicate username
- Duplicate email address
- Duplicate first name AND surname
- Spammy email domains (such as throw away email accounts)
Also, it might be worth pointing out that ‘Then the registration is successful’ (or fail) is also vague. How do we know it’s successful? Will it show a display message? Will the data be set up in the database? There is no right or wrong here. Depending on the project that you’re working on, you may not even need to specify and that’s ok.
Let’s say we were going to base it upon the email address. If we were to improve it, we would now have something like this.
Given user account with email "john@doe.com" does not exist
When a user tries to register with "john@doe.com"
Then the registration is successful
Given user account with email "john@doe.com" exists
When "john@doe.com" tries to register
Then the registration fails
The test data problem
This looks better, doesn’t it? But there is a second issue which relates to test automation. The tricky part is setting up test data (aka setup and teardown). In other words, what if we finished running the automated tests and need to repeat them? “john@doe.com” will now exist in the database so the first scenario will fail. Easy solution, don’t talk about john.
When a new user tries to register (email does not exist)
Then the registration is successful
When an existing user tries to register (email does exist)
Then the registration fails
Under the hood, we could generate random data when automating tests.
One scenario or two?
These scenarios have a single action of ‘register’, so we can combine them into a scenario outline.
Scenario Outline: A user can only register once
Given there is a user with email in <State>
When the user attempts to register
Then the registration is <Outcome>
Examples:
|State|Outcome|
|Exists|Success|
|Does not Exist|Failure|
I know that saying ‘user’ is may not the best practice here since it means nothing. A further improvement might even be to call it ‘customer’ or what makes sense in your business.