Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gherkin - simply re-use Given statements as When statements... acceptable?

Here are three example BDD statements that should help explain my question:

Scenario: User logs in
Given I am on the login screen
When I enter the valid username "myUsername"
And I enter the valid password "myPassword"
And I press the login button
Then I should see the login successful page

Scenario: User buys a product
Given I am logged into the system using username "myUsername" and "myPassword"
When I purchase the product "myProduct"
Then I should have "myProduct" in the product inventory

vs

Scenario: User buys a product
Given I am on the login screen
And I enter the valid username "myUsername"
And I enter the valid password "myPassword"
And I press the login button
When I purchase the product "myProduct"
Then I should have "myProduct" in the product inventory

So scenario 1 above is fine, but which is best out of statement 2 and 3. Statement 2 reads nicely and more concisely. But my step definition for "Given I am logged into the system using username "myUsername" and "myPassword"" will need to repeat calls to the Page Objects (or equivalent) that scenario 1 called... seems like more dev effort.

So really just wondering if anyone knows which is best practise. I have searched online and found the following document: http://docs.behat.org/guides/1.gherkin.html

This suggestions scenario 2 is best, but then writes: "Authenticate a user (An exception to the no-interaction recommendation. Things that “happened earlier” are ok)" which kinda lends itself to scenario 3.

Cheers,

Charlie

like image 661
Charlie Seligman Avatar asked Jan 10 '14 16:01

Charlie Seligman


People also ask

What is Gherkin acceptance criteria?

Gherkin is a Domain Specific Language for writing acceptance criteria that has five main statements: Scenario — a label for the behavior you're going to describe. Given — the beginning state of the scenario. When — a specific action that the user takes. Then — a testable outcome, usually caused by the action in When.

What is the two main purpose of using Gherkin?

Gherkin is a Business Readable, Domain Specific Language created especially for behavior descriptions. It gives you the ability to remove logic details from behavior tests. Gherkin serves two purposes: serving as your project's documentation and automated tests.

Which one among the following keyword does Gherkin language uses to describe the behavior of applications?

Background. This keyword is used to define the steps that are common to all tests in the feature file. For example, Navigation to Home Page, Click on the Login, Enter User Name and Password, Click on Submit button are the common steps in almost all web applications.


1 Answers

Here is my review of the scenarios you've written.

Scenario 1

Scenario: User logs in
Given I am on the login screen
When I enter the valid username "myUsername"
And I enter the valid password "myPassword"
And I press the login button
Then I should see the login successful page

Pros : You are correctly using the Given, When and Then statements. In this scenario the Given sets the initial state of the system, the When indicates actions which a user will take and the Then details the assertions made to verify the behaviour of the system.

Cons : Whilst what you have written will work, the problem you have is that this test is brittle. If your company was to mandate that a time-dependent security token also had to be specified during log-in (for example), you'd have to add another step to input this additional field. However if you rewrote this step to be declarative e.g.

Given I am on the login screen
When I submit valid log-in criteria
Then I should see the login successful page

Then if the log-in process was changed, you would only need to alter the code, the scenario would remain the same.

Scenario 2

Scenario: User buys a product
Given I am logged into the system using username "myUsername" and "myPassword"
When I purchase the product "myProduct"
Then I should have "myProduct" in the product inventory

Pros : Same as above.

Cons : Again the test is brittle as it's imperative i.e. you are specifying the exact log-in credentials and a specific product. I'd re-write this as:

Given I am logged into the system
When I purchase a product
Then I should have that product in the product inventory

You can save the product specified in the "When" step in ScenarioContext.Current. You would then be able to re-use this value in your "Then" step to assert that it is present in the product inventory.

Scenario 3

Scenario: User buys a product
Given I am on the login screen
And I enter the valid username "myUsername"
And I enter the valid password "myPassword"
And I press the login button
When I purchase the product "myProduct"
Then I should have "myProduct" in the product inventory

Cons : This is the worst of your scenarios as you are incorrectly using the Given statement. A Given statement should be used to define an initial system state for the test, so in this case "Given I am on the login screen" is a correct use, but "Given I enter the valid username "myUsername"" is an incorrect use. It is incorrect as it is indicating a user action, hence it should be covered by a When. Yes, you can use a Given to perform the same programmatic steps as a When, but it doesn't make it right!

I'd change this scenario to the version I suggested in Scenario 2.

like image 181
Ben Smith Avatar answered Nov 05 '22 16:11

Ben Smith