Does if else concept available in feature file (Gherkin language)? - cucumber

Is there anyway where we can use if/else concept in feature file? For example:
Scenario: User should be able to check login page
Given I am on login page
When I click on SignIn button
Then I should be in home page
If yes
Then I will create a new profile
Else
Then I will logout from page

Not that I am aware of. Gherkin (and cucumber) are best used when they specify discreet business cases though, and should be repeatable, else they get hard to follow and test. It looks like you have two stories here at least:
Scenario: A new user should be asked to sign in
Given I am a new user
And I navigate to the login page
When I click on SignIn button
I should not be able to get to the home page
Scenario: An existing user should be able to log in
Given I am an existing user
And I navigate to the login page
And I submit valid credentials
When I click on SignIn button
I should be taken to the home page

No you can't and you shouldn't. Feature files are for business behaviour, not programming.
From your scenario I think you are trying to deal with different behaviour, depending on whether you are registered or not. To do this you would write two scenarios
Given I am registered
When I
Then I should ....
Given I am a new user
When I ...
Then I should be asked to register
Notice how these scenarios don't describe 'how' anything is done. Anything like `I click on foo' in feature is a smell and should be avoided.

You would like to twist your scenario as below
Scenario: User should be able to check login page
Given I am on login page
When I click on SignIn button
Then I should be in home page
And check if home page exist and store result as existence
If existence is true
Then I will create a new profile
And Else
Then I will logout from page
In the step definition for And check if home page exist and store result as existence is Check home page exist or not by checking the driver.findElement returns null or not and based on it store it as true or false in thread context instance with key as existence
In the step definition for If existence is true retrievie the thread contenxt instance data for key existence as asserts it if its true or false and store it with key conditionresult in thread context instance.
In the step definition for Then I will create a new profile before creating the profile retrieve thread context instance data for key conditionresult and check if value is true then create the new profile and set again thread context instance for conditionresult as null with in the condition loop.
In the step definition for And else retrieve the thread context instance for conditionresult and check if its false and if yes set again thread context instance for conditionresult as true
In the step definition for Then I will logout from page retrieve the thread context instance for conditionresult and check if its true then perform logout and set again thread context instance for conditionresult as null with in the condition loop.

What about if we are using Gherkin in a smoke test type situation and we need to ensure something exists in the database using only the UI?
Scenario: I need to create one (and only one) Box before I run the rest of my smoke tests
Given I login as Admin
When I am on the Box list Page
Then the test passes if the Box named "QA SmokeTest" exists
When I click the Add New Box Button
And enter the details for a New Box
And press Save New Box
Then the test passes if the Box named "QA SmokeTest" exists
The re-use of the same Then step twice is essentially an if-else that will make sure my Box exists so that I can run my other tests in the smoke test suite that require a Box.
But that is dependent on being able to stop the Scenario execution in the test runner or doing something extraneous like:
ScenarioContext.Current["TestPassed"] = true;
and then in each of the steps
if(ScenarioContext.Current.Get<bool>("TestPassed")) return;

You can use parameter in feature file and implement the If else in the Code based on the parameter passed.

Related

How to implement 'if' in Gherkin

I am trying to convert Selenium test to Gherkin. Is there way to implement if statements in Gherkin?
Example : assume the code is written in the below format. I am just writing description as below. Please understand the part after double slash is the actual Selenium code:
// launch the application
// login to application
// navigate to page
String str;
if(str== "XYZ")
{
// verify title
}
//verify text field 1
//verify test field 2
//verify select box
For this I am trying to write code in Gherkin as follows
Given user launches the application
When user login with valid credentials
and navigate to required page
When String str is "XYZ"
Then verify title
And verify text field 1
And verify test field 2
And verify select box
but this code is incorrect because if the str is not equal to "XYZ" we want that title should not be verified but other verification like text field1,2 and select box should be verified.
You don't implement if in Gherkin.
Gherkin is about communication and those you want to communicate with, non coders, don't know what an if statement is. They don't care either.
The solution? Two scenarios to cover both cases.
Ideally, this level of detail would not be in your Gherkin scenario. The best approach is describe business use cases, not low level details. This is what Gherkin is designed for: communicating with non-technical stakeholders so that you can work out if you are building the right thing in the first place. Here is what I would write:
Given the user is logged in
And the user is on the required page
When they enter data that requires the optional fields to be validated
And they enter invalid data in the optional fields
Then the form shows an error on the optional fields
The low level details don't matter (that the string is specifically "XYZ" or that it is the title field is not important), so these should be hidden in the step definition and/or unit tests.
In order to continue to check the other fields, you can just add another step after this:
When they enter invalid data in all of the other fields
Then each other field has an error message attached to it.
Again, there is no need to specify the actual fields, or separate them into their own steps. The idea is to express the high level business value of the scenario, i.e. that the form is validated when it should be.
The advantage to keeping things high level is that when the form changes (as it eventually probably will), then this scenario can remain untouched. Which is correct as the business case is the same: it should validate when it's supposed to. All the changes will be in the step definitions. This means that there is no reason to have another discussion with your stakeholders about whether your scenarios are still testing the right thing.
You can write the scenario, somewhat like this:
Given the user launches the application
When user login with valid credentials
And navigates to required page
Then he should see the page datails
Inside the Then step you manage all the logic.
Then(/^he should see the page details$/) do
if condition
...
else
...
end
end
Gherkin is not a programming language to use if or else conditions. It is a part of BDD framework, that is implemented, to make the stakeholders and other non technical resources understand what the test process is about. Hence, it is always recommended, you keep the gherkin as simple and as generic as possible.
Strictly speaking you should create an alternative statement along the lines of:
Given user launches the application
When user login with valid credentials
and navigate to required page
When String str is NOT "XYZ"

How to Login only one time and then run a lot of scenarios

I'm a newbie in BDD and i would like to know how can i do some step before the beginning of my scenarios but only one time.
Concretely, i would like to login in my website and do some scenarios.
Currently, i have a background which log my user and after i have some scenarios.
The problem is that for all of them, my background is repeated.
How can i do to avoid that ?
Thank you in advance.
Feature:
User's module verification.
As a user, i have to be able to manage my profil.
# Background do an user's connection and go to his profile.
Background:
Given I am logged in
# -------------------SUMMARY MANAGEMENT---------------------
#javascript #success #raz #summary
Scenario: Deletion of the summary.
When I click on the element at xpath "//*[#id='presentation']"
And I write in the element at xpath "//*[#id='profile-content-presentation']/div/div/div[2]/div/span/div/form/div/div[1]/div[1]/textarea" value ""
And I click on the element at xpath "//*[#id='profile-content-presentation']/div/div/div[2]/div/span/div/form/div/div[1]/div[2]/button[1]"
And I wait for 1 seconds
Then I should see "Aucun résumé pour l'instant"
You could use behat hooks to automatically log user in before every scenario.
You could also combine this with tags to avoid logging user in, in scenarios taged in a certain way (or do the opposite, depending on how many of each you have).
Also see Behat Mink webdriver session is destroyed after every feature in a suite

How to add action in then section of cucumber?

I'm new to cucumber and I wonder how can I test the following scenario:
user, that is not signed in, clicks on "buy" link on my site
popup with login/passwords shows
user fills login and password fields and then click 'Sign in'
page reloads
user clicks again on "buy" link and see popup with order details
I have problem with defining "Then" section, because for me it should be:
Then
When I click "buy"
I should see "order details"
Is this possible with cucumber?
Scenario should have a single testing goal. With your current scenario you have 2 goals so it may be better to write 2 scenarios:
Possibility of login after clicking buy
Ability to see order details after clicking buy.
I don't understand why you want to do this using 1 scenario.
That said, Cucumber doesn't distinguish between Given, When and Then at step definition layer so you can write like this:
Given ...
When ...
Then ...
When ...
Then ...
The feature file would look like this (simplified):
Feature: View Order Details
As a user I can process an order
Scenario: Process Online Order
Given I am logged in
When I click "buy"
Then I should see the order details

Is it possible to reuse a feature as the "Given" for another feature?

Is it possible to reuse a feature as the "Given" for another feature?
Or am I trying to do something I shouldn't be trying to do
basically my features look like:
Scenario: Creating a basic account with valid details (happy path)
Given I am on the "signup" page
And I enter all the right details #this is shortened of about 20 steps for your reading ease
When I press the button labelled "Sign up"
Then I should see the text "Thanks for signing up"
And I should have an email from "confirmation#mysite.com" titled "Confirm your account Michael"
And the database should contain a record for the user marked as unconfirmed
Scenario: Confirming account via email
Given I have created a basic account
When I open the confirmation email and visit the url to confirm the account
Then I should be logged in
And the database should contain a record for the user makred as confirmed
I clear my DB after every feature as they should all be able to be run individually...
Am I going about this the wrong way?
Thanks
The Problem
What you're actually attempting is to reuse a scenario. This is no longer supported in Cucumber.
Aside from other problems with this approach, your tests will be slower and interdependent, since you will be:
driving account creation through a browser, and
making all your tests dependent on the account-creation test passing.
Don't do that.
The Cucumber Way
Generally, you should write your tests to work independently, although you can certainly reuse step definitions. So, in the general case, you might want to add shared steps like:
Given that user account "Test User" does not exist
Given that user account "Test User" exists
which can then be included in your scenarios as needed. The nice thing about this approach is that the steps can create or delete users programmatically.
Alternatively, if most of your tests will be on existing accounts, set up the default data set with the right user fixtures already in place. For the limited subset where you will be testing account creation, just add a scenario background that drives user deletion.
In case you are using Javascript, I've created a package named reuse-cucumber-scenarios for calling a scenario by doing:
Given the scenario "#scenario_tag"
.
Given the scenario "#scenario_tag" with parameters
"""
{
"1": ["step1_param1", "step1_param2"],
"2": ["step2_param1", "step2_param2", "step2_param3"],
"3": ["step3_param1", "step3_param2", "step3_param3"],
}
"""
or creating gherkin variables...
Given the variable "$variable_name" is equal to
"""
#JSON object
"""
or creating scenario functions and calling them by doing...
Given the scenario "#$scenario_function_tag" where variable "$variable_name" is "value_to_replace"
and more...
Currently, you can use the following approach:
Background:
Given Some common setup
And Some more setup
Scenario: one
When setup1
Then something1
Scenario: two
When setup2
Then something2

BDD - Cucumber: Is possible to disable Background logic for only one scenario in feature?

In a feature file have a Background and several Scenarios, but now need a Scenario related to same feature that don't have to run background logic, is possible to disable for only a scenario?
UPDATE - Add Example:
Feature: Sign Up
In order to access to protected parts of site
A user
Should sign up
Background:
Given I am on sign up page
And I am not logged in
Scenario: User sign up succesfully
When I sign up with valid fields
Then I should view dashboard page
Scenario: User altredy sign up
When I sign up with altredy registred user e-mail
Then I should view altredy sign up message and link to forgot password page
Scenario: User try to sign up with missing/wrong data
When I will try to sign up with missing/wrong data
Then I should error message
Scenario: User altredy sign in
#here disable background
Given I am logged in
When I am on sign up page
Then i should be redirect to dashboard page
Solution 1.
You could put that only Scenario in other Feature file where there's no background or it has it's own background
Solution 2.
Remove the background from the feature file and then put its logic on the step definitions, something like
Given 'I am on sign up page' do
some code here
end
Given 'I am not logged in' do
some code here
end
then on each first step
Given 'I sign up with valid fields' do
step 'I am on sign up page'
step 'I am not logged in'
the rest of your code for this step
end
Given 'I sign up with altredy registred user e-mail' do
step 'I am on sign up page'
step 'I am not logged in'
the rest of your code for this step
end
Given 'I will try to sign up with missing/wrong data' do
step 'I am on sign up page'
step 'I am not logged in'
the rest of your code for this step
end
This is not pretty though you would repeat those at least 3 times.
Solution 3.
You could get rid of that Scenario and paste it's steps in the first Scenario, something like
Scenario: User sign up succesfully
When I sign up with valid fields
Then I should view dashboard page #this is your Given I am logged in step
When I am on sign up page
Then i should be redirect to dashboard page
I would get rid of the background clause entirely - it's unnecessary detail. Your scenarios make perfect sense without it.
You can visit the signup page, and verify the user isn't already signed in, as part of your "When I sign up with valid fields" step definition.
Why don't you create a step definition that closes that session?
something like this:
Then(/^I close the browser$/) do
page.driver.quit
end
Then you do whatever you need in your subsequent steps
If you have this need then you have identified a new feature. So instead of trying to be clever with cucumber you can just take the simpler approach of being clever with naming your features.
With your example the scenario User already signed in clearly has nothing to do with signup, it belongs in a different feature e.g.
features
- signup.feature
- signed_up.feature
Other names for signed_up might be default_navigation, first_sign_in etc. etc.
Wanting a different background for a different part of a feature is always an indicator that you have two different bits of behaviour you are exploring.
Maybe you can name your feature files using numbers in which 0_exaple1.feature file you can run those test cases where you are using the Background and 1_exaple.feature file you can run those cases which you want to run without background and provide the same tag in both the feature file and give that tag in runner file
your runner file is something like this:
#CucumberOptions(
features = {"src/test/resources/features"},
plugin = {"com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:"},
glue = {"com.company.comapnies.stepdefinitions"},
tags = "#test"
)
and under the feature folder, your file should be saved like this
feature
|_
0_example.feature
1_example.feature
and your 0_example.feature file like this:
Feature: Sign Up
In order to access to protected parts of site
A user
Should sign up
Background:
Given I am on sign up page
And I am not logged in
#test
Scenario: User sign up succesfully
When I sign up with valid fields
Then I should view dashboard page
and 1_example.feature file like:
Feature: Sign Up
In order to access protected parts of the site
A user
Should sign up
#test
Scenario: Run this scenario without background
Given: Launch the browser
And: Do something
So when you run your test runner file then it will automatically pick the #test tag, search in 0_example.feature first, and then, 1_example.feature file will start executing.
This is the only thing you can run in your framework as of now to prevent background runs.
Cheers!!!

Resources