I've got a feature (a .feature file) that are working fine in cucumber.
The background of all the scenarios in the feature just sets up a user, and then logs in as a supervisor, e.g.
Background:
Given I am logged in as a supervisor with an existing supervisee
...loads of scenarios
However the design/goals of the application has changed and the same scenarios should all work whether you are logged in as a supervisor or as the user. This is not true for most of the rest of the application where the design is not symmetrical for supervisors/users.
Is there any sane way to avoid copying and pasting the whole of the feature file with a different background? It doesn't seem like there's a way to either parameterize background (e.g. with an Either: Or: stanza) or alternatively a way to pull in an external file with a load of scenarios. Ideas?
Background:
Given I am logged in as an existing supervisee
...same loads of scenarios
Here's some fantasy gherkin syntax (that doesn't exist)
Background Outline:
Given I am logged in as a <user>
Backgrounds:
| user |
| supervisor with an existing supervisee |
| an existing supervisee |
...loads of scenarios
Alternatively different fantasy Gherkin syntax :
Background:
Given I am logged in as an existing supervisee
Include Scenarios:
supervisor.features
If it was me, I would just suck up the duplication:
http://dannorth.net/2008/06/30/let-your-examples-flow/
An alternative would be to use a tag on the feature that indicates you want to run the scenarios against both user groups. Then use an Around hook to run the scenario twice, once for each type of user.
We've talked about things like Background Outlines before, but the conclusion we came to was that it wouldn't be worth the extra complexity to implement it.
Related
I want to add pre-steps to Scenario Outline as Scenario, but I don't want to add pre-condition. How can I do that in Jira Xray?
Some illustrative example:
Scenario:
Given: Open website
Then: Check URL
Scenario Outline:
When I click this <button>
Then Something happens with <this> element
I want to have some "background" for Scenario Outline because this is something that repeats in several tests but it turns out that for every step in S.Outline Background is repeating so I want to create a normal Scenario as "artificial" background. How to do that in Xray? Can I add something like pre-step? Pre-condition always creates "Background" in Gherkin.
I don't want to have several Scenario Outline scenarios with a lot of repeated steps.
This is more a Gherkin related question than Xray specific. There are no dependencies between Scenarios in Gherkin.
The way to have some initial Gherkin statements that apply to all to several Scenarios, is by having a Background in the corresponding .feature file.
In Xray this means that you need to have a Precondition, of Cucumber type, with those Gherkin statements. Then you need to associate it all Tests (Scenario/Scenario Outline types) that you want. Whenever exporting those tests, a .feature file will be created with a Background corresponding to the previous Precondition.
The rules for generating .feature files based on Test and Preconditions issues in Xray is detailed here.
Note: in Cucumber libraries there also hooks, that contain code that can be executed before/after tests. However, this is used for something that isn't described as behaviour and more for easing implementation, and doing things like test setup/cleanup.
I am doing BDD test on an app with cucumber, and I want to have clear instruction as it is recommanded in cucumber doc. The thing is that we have to do reusable step definitions so the maintenance cost is acceptable.
Example of scenario we have
Given I am on project page
When I click on 'buttonAddProject' //not easily readable
And I click on 'switchProjectPrivate'
And I click on 'buttonDeleteProject'
etc..
I don't want to have a function for each step like that: I change projet visibily or I delete project,
because this is basically just a click on a button, and we are going to have hundred of function like this. I also can't change the param in key to something more suitable, because every button key should be unique to avoid ambiguity.
So is there a way to do this with cucumber ?:
Given I am on project page
When I click on 'Add' //easily readable
And I click on 'Private'
And I click on 'Delete'
Bindings: //this keyword doesn't exist
'Add' : 'buttonAddProject'
'Private': 'switchProjectPrivate'
'Delete':'buttonDeleteProject'
I have tried that:
Scenario Outline:
Given I am on project page
When I click on <Add> //easily readable
And I click on <Private>
And I click on <Delete>
Examples:
|Add |Private |Delete |
|'buttonAddProject'|switchProjectPrivate'|'buttonDeleteProject'|
it works... but I need to do this for every scenario in the file, and if I really want to use scenario outline to iterate several times, I would have to copy paste this for every line, not really what I want.
How to organize this tests to make them more readable without making things to complex ?
First of all Cucumber scenarios that show HOW each thing is done are not maintainable or particularly useful.
What are cucumber scenario should describe and document is WHAT you are doing. To do this you need to determine WHY you are clicking on these buttons and what is achieved by these actions.
Now I have no idea from your scenarios about WHAT you are adding, WHY it is private or WHY you are then deleting it. But I can speculate from your post. The scenarios you should be writing should be something like.
Scenario: Delete a project
Given there is an existing project
And I am viewing the project
When I delete the project
Then ...
Scenario: Create a project
When I create a project
Then a project should be created
When you write your scenarios in this manner you push the details of how you interact with your UI down into your step definitions. So you might have something like
When 'I create a project' do
visit project_page
click "Create Project"
end
or better just
When 'I create a project' do
# must be on project page
click "Create Project"
When you work this way step definition re-use becomes less relevant and valuable. Each step does more and does something more specific.
You can continue this pattern of pushing the HOW down by having step definitions make calls to helper methods. This is particularly useful when dealing with Given's which get alot of re-use. Lets explore this with Given there is an existing project
Given 'there is an existing project' do
#project = create_project
end
Here we are pushing how we create an existing project down into the helper method create_project. The crude way to this would be to go through your UI visiting the project page and adding a new project. However this is really slow. You can optimise this process by bypassing your UI.
The most important point, whatever you decide to do, is that you are taking HOW you do something out of Cucumber and into some underlying code so now Cucumber is only interested in WHAT you are doing and WHY its important.
Making this change is probably the single most important thing you can do when Cuking. If you keep the HOW in your cucumber scenarios and step definitions you will end with a large number of brittle step definitions and very large scenarios that break all the time because everything is coupled together. You will get lots of bugs where making a change to get one step definition working causes lots of other scenarios to break. You will get lots of bugs where small changes to how you do a particular thing cause lots of unrelated scenarios to break.
Finally you are not doing BDD if you are writing the test after the code has been written. You can only do BDD if you write your scenarios collaboratively before the code is written.
Each step must be tied to a step definition. If you like to reuse an existing step def, you can just pass the command as argument (" Add", "Private","Delete"). You will have to use both the scenario name and the corresponding command to perform the required action.It will be something like this,
Scenario: scenario1_deleteproject
Given I am on project page
When I click on 'Add'
And I click on 'Private'
And I click on 'Delete'
Scenario: scenario2_createproject
Given I am on project page
When I click on 'Add'
And I click on 'Private'
And I click on 'Delete'
The step definition:
#When("When I click on {string}")
public void I_Click_On_Something(String command)
{
Switch(Command)
{
case Add:
//perform steps here
case delete:
//perform steps here
default:
}
If you want to differentiate the commands between the scenario, you will have to use scenario name ( need a class with definitions of scenario & command). You can grab the scenario name #Before hook.
I have to execute certain Examples from Scenario Outlines.
Let's see the following example:
Feature: Temp
Scenario Outline: Test.Something.On.<environment>
When action is performed on "<environment>"
Examples:
|environment|
|lab |
|prod |
I would like to execute only the example with lab from the upper presented Examples.
I tried the followings:
Filter by line number: mvn clean test -Dcucumber.options="src/test/resources/features/Temp.feature:8" - this way only the lab scenario was executed, however this is not a long term solution;
Filter by name: mvn clean test -Dcucumber.options="name lab" - it works for Scenario but not for Scenario Outline even if the name of the scenario will be Test.Something.On.lab;
decompose the Scenario Outline in Scenarios and tag the proper scenarios with #lab and #prod - I hate code duplication and the subsequent maintenance, therefore I hope there is an another solution for this.
Any suggestions?
Big thanks.
Another sub-keywords: maven, java, cucumber-java8, cucumber-junit, junit
Use two examples in yoour scenario outline and tag each example in a similar way as you have done in your third option. That should give you the behaviour you are asking for.
I started working with behavior driven tool cucumber. Its a fun tool to use. While i was working on a problem. I came across that most of time, I am not reusing my code.
That's why I want to call a scenario from another scenario. I have searched but found nothing helpful. Can I do that ?
Another same question posted here on github
This may be what you're looking for: https://github.com/cucumber/cucumber/wiki/Calling-Steps-from-Step-Definitions
So there are a couple of things you can do. If you have a step you want to reuse like the following:
Given /^I log in as (.*)$/ do |name|
# ...
end
You can call it within another step like so:
Given /^(.*) is logged in$/ do |name|
step "I log in as #{name}"
end
You can also do the following within a step definition:
steps %Q{
Given I log in as #{name}
}
I came to the same question - and found this post. Maybe it is on purpose that you cannot call Scenarios from other Scenarios. The framework is based on that you think about creating practical Stepdefinitions, so they can be used many times. The basis is to think before creating steps...
I created own Steps vor Login-Method, Pagetransitions to search-page or new File etc..
So in many Scenarios i reuse these Steps - and then add new ones (that can be reused, too).
Now you can think about how big one step should be. You can size it as one action in the testobject or use it as a routine to come to a certain startpoint of your Test over multiple actions. E.G. Given Go to Startpage of creating a security request
Java Code:
#Given ("^Go to Startpage of creating a security request$")
public void GoToStartpageOfCreatingASecurityRequest(){
//logic to get to the demanded point in testobject...
}
So as any other framework cucumber has its limits but they are intended and you have ways to work around it. ;)
Do not forget to use assertions in your test. Wether you use JUNIT or TestNG (I use TestNG). ;)
Can DalekJS call or use a previous test (like a login test) and continue once that test has completed? I would like to write my test files as singular tests so that individual people are able to edit only a small portion of it.
I would like to test if a menu item actually links to a page, but call the test that checks if a user can login to the site as the menu item test requires that the user is logged in.
As DalekJS files are just "normal Node.js" files, you can basically do whatever you want ;)
I have some resources on how to keep your tests DRY & modular, go and check out this repository https://github.com/asciidisco/jsdays-workshop/tree/8-dry I made for a workshop. To be more specific, these files in particular:
https://github.com/asciidisco/jsdays-workshop/blob/8-dry/test/dalek/form2.js https://github.com/asciidisco/jsdays-workshop/blob/8-dry/test/dalek/functions/configuration.js https://github.com/asciidisco/jsdays-workshop/blob/8-dry/test/dalek/functions/formHelper.js https://github.com/asciidisco/jsdays-workshop/blob/8-dry/test/dalek/functions/selectors.js