I have a cucumber feature called "A" located at "C:\cucumber tests"
Now I want to create another cucumber feature call "B".
The first part of the steps of feature "B" will be exactly the same as in feature "A". I don't want simply to copy all the steps in feature "A" to feature "B"
Is there anyway to call feature "A" in feature "B"?
I appreciate it.
ruby version:
I don't believe you can call an entire scenario, but you can call steps from a step using the steps method.
Given /^(.*) is logged in$/ do |name|
steps %Q{
Given the user #{name} exists
Given I log in as #{name}
}
end
This will at least allow you to reuse your stepdefs, but not your scenarios.
For more information see Cucumber Docs
If you are willing to put the features in the same file, you can use the background to run the same steps for each.
Background: Login the user
Given I have an admin account
And we have a user named "john"
And I am logged in
Scenario: Reset Password
When I reset the users password
Then the server sends an email to "john"
Scenario: Lock User
When I lock the account for "john"
Then "john" cannot log in
Related
If you have a simple form, you enter your name, Gender and save it. When you select the Gender drop-down it will list [Male | Female].
So when writing test scenarios for the above, the typical way is to Write it in steps.
Precondition : User Loged in and Form Opened
Steps | Expected Result
------------------------------------------------------------------------
1 : User Enters the name | Entered name should be there
2 : User Clicks on Gender Drop-down | Male and Female should be listed
3 : Users Selects a Gender | Selected Gender should be there
4 : Clicks on Save | Information get saved.
Following is one way to represent this is Cucumber.
Given User Loged in and Form Opened
When User Enters the name
Then Entered name should be there
When User Clicks on Gender Drop-down
Then Male and Female should be listed
When Users Selects a Gender
Then Selected Gender should be there
When Clicks on Save
Then Information get saved.
Now How can we represent this in Cucumber? As I read you are not suppose to have multiple actions within the same scenario. If you add multiple testcases for each step above, the Testcases will grow exponentially. What is the best way to handle this?
My approach would be to think about documenting in Gherkin (using principles of BDD) - the application behavior and not test cases.
In fact, this article provides some good context around misconceptions of BDD.
With that said, even though you are trying to validate the above criteria in a single scenario, I would recommend at least splitting into 2, to keep your acceptance tests succinct, readable and maintainable.
Here's my attempt, at reformulating:
Scenario: Gender Dropdown values
Given a user is logged in
When the user clicks the Gender dropdown
Then Male and Female options are displayed
#EndtoEnd
Scenario Outline: Saving User information
Given a user is logged in
When the user enters a <Name> and selects a <Gender>
And Clicks on Save
Then the information gets saved
Examples:
|Name|Gender|
|Keith|Male|
|Jenn|Female|
||Female| # Negative
|Rob|| # Negative
Additionally, you can also think about throwing in some negative test scenarios as well.
If you need to test on cucumber with multiple data, you can go ahead and use the scenario outline feature, where you load the data in the examples after the scenarios.
Scenario Outline: User enters details and stores
Given User Loged in and Form Opened
When User Enters the <Name>
And Users Enters the <Gender>
And Clicks on Save
Then Information get saved.
Then I Go back (In case view info)
Then I assert for <Name>
Then I assert for <Gender>
Examples:
|Name| |Gender|
|x| |Male|
|y| |female|
Cucumber is not about testing how you do things, its about specifying why you do things. This scenario is all about how the user interacts with the form, its all about clicking on this and entering that, none of this has any place in scenarios.
Your scenario and question doesn't even tell us what you are trying to do, so I'll just have to make something up. Lets say you are trying to add a friend
Feature: Adding a friend
Scenario: Add Alison
Given I am logged in
When I add Alison to my friends
Then I should see Alison is my friend
and thats pretty much that. Note how none of the details about how you add a friend are captured in the scenario, thats not what Cucumber is for.
Now on the technical side lets explore how we get this scenario to actually add a friend. First of all the step definition
When 'I add Alison to my friends' do
add_a_friend name: 'Alison' # perhaps add a gender param here
end
Notice how even the step definition doesn't know how to fill in the form.
Finally a helper method to actually do the work (done in Ruby cos its clearer)
module FriendStepHelper
def add_a_friend(name:)
# here is where we fill in the form and choose the gender
end
end
World FriendStepHelper # makes add_a_friend visible to step def
So technically this is how you represent your problem in Cucumber you write WHY you doing things in using your scenarios and you push down HOW you do things to helper methods used by your step definitions
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
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.
Firstly, there is absolutely nothing in Gherkin that prevents you from writing specifications in any order, you can even produce compound specifications such as
Given ...
When...
Then ...
When ...
Then ...
Given ...
When ...
Then ...
So why would you want to do this?
Well first lets consider a fourth variant of your scenario
Scenario: User logs in and buys a product
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
When I purchase the product "myProduct"
Then I should have "myProduct" in the product inventory
This is of course just a compound of 1 and 2. You might have written this because you had finished testing login and wanted to quickly write and test buying a product. You already have the code for the Bindings in scenario one and now simply need to write the bindings for scenario two. You might consider this your simplest pragmatic change, and you will refactor it later. This nothing wrong with it, running the tests could be quicker, but also its not exactly ideal.
Now imagine that due to the nature of your shop you have written many tests that test different buying processes. We could be testing what happens when you add the same item again to your basket, or if you try to buy something out of stock, or different checkout experiences if you want special delivery. In fact your shop is so successful that you need to be really secure on the web and change your login process. Unfortunately you now have those three lines
Given I am on the login screen
When I enter the valid username "myUsername"
And I enter the valid password "myPassword"
repeated throughout your scenarios. If we accidentally break our login process with some bad code, suddenly all of our tests fail. You are presented with a wall of red and can't really narrow down where to start looking at the problems. Because we are dependant on logging in before we run our scenario we cannot isolate login from purchase.
This really is the difference between a Given and a When. A When is there to indicate that we are performing a process, a Given is a means of directly affecting the run time environment so that we simply have the correct state. It's basically the difference between
//Given
isLoggedIn = true
//When
if CheckValidPasswordForUser(user, password)
isLoggedIn = true
The Given has no way to fail.
So coming all the way back to your original question,
Can you re-use Givens as Whens? Yes, but it in the long term it will confuse you.
But if you ask Can you re-use Whens as Givens? then I would definitely advise you not to. This will hide the fact that something that could break is being tested.
Finally there is one other thing to consider and that is the domain of your specification. Dan North has a really good article on this Whose Domain is it anyway?, but the general gist as applied to your example here is that when you are looking at product buying you can simply write
Given I am logged in as a customer
or
Given I am logged in as an administrator
because the username and password parts are to with login and not products, and that way you are protected from re-writing all your scenarios when you change your login process to use something else.
I am using load runner 9.5. I am facing a problem during Dyanmic data handling. Scenario is given below-
I have Library management application. Login-> Select book(data display based on User credential) -->Purchage and Logout.
Ex: Guest user: 50 Books display to choose
Admin : All Books display choose
Normal user : 100 Bokks display choose
Please help me How to handle these type of dynamic data based on user role. Is there need to create different script with different role ?
Please follow the below steps -
Record the same flow with the same user credential 2 times (Replica of first script)
Compare the scripts using W diff
Find the values which are different like purchase order, timestamp and user session.
Correlate the values which are highlighted in yellow means value which is different in each script.
Have you had the benefit of training in LoadRunner and a mentor for your first year of work in this field?
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
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!!!