I need to write a class for enforcing rules about items which may or may not be added to the same container in a warehouse, and I'd like to translate the requirements in to Cucumber before implementing it.
Each item has several attributes, such as "Item Family" (eg: electronics, book), "Item Status" (eg: main stock, faulty stock), and "Batch" (eg: 1050, 1051).
I can think of several strategies for writing a Cucumber test for this, and I'd like to know which is the recommended one:
Firstly, you could enumerate all of the attributes per product:
Given I have a tote containing:
| sku | client | family | status | batch | weight |
| 100000 | Foo | garment | main | 1234 | 10 |
When I add the item:
| sku | client | family | status | batch | weight |
| 200000 | Bar | garment | main | 1234 | 10 |
Then I should be told there is a Client conflict
Secondly, you could have a basic product hard-coded, and try specifying the minimum differing attributes from it:
Given I have a tote containing an item that's client "Foo"
When I add an item that's client "Bar"
Then I should be told there is a Client conflict
This assumes the step definitions hold the basic attributes, and override them when attributes are mentioned in the steps.
Finally, you could go a further step of abstraction:
Given I have a tote containing an item
And I add an item with a different client
Then I should be told there's a client conflict
Any guidance on the correct approach here?
The answer from The Cucumber Book would be whichever is most readable to the non-technical members of your team. Sit down with the QA lead and project manager, and ask them the same question. I had a similar problem, and started with something like your first suggestion. Then I decided it was too detailed and jumped to #3. Then I sat down with the project manager and found out that when I was creating the data I did not need any detail, but when we changed the data (in our case updating line item values on an invoice), we wanted to see what those values were in the steps.
Chapter 6 from The Cucumber Book "When Cucumbers Go Bad" was really helpful in directing to the right level of detail. I really think you should give it a read, especially the part about coming up with an Ubiquitous Language. I think that will help you decide on the right level of detail for your organization.
If you are tempted to use the first test, my question to you would be, "How often are you going to change those values?" If the answer is "not very" or "never", then you should consider whether they are adding to or detracting from the readability of the test.
P.S. I'm still reading The Cucumber Book, but so far it has been extremely helpful, for example pointing me towards FactoryGirl as socjopata suggested.
First option mentioned is the one that's most flexible and reusable. With the first approach you can cover basically any case you may need, but there are some cons, that you'll read about below.
The 2nd and 3rd options are easier to read, which is also an important factor while writing tests. Furthermore, the seem to focus on what is actually tested, i.e the key difference which "Foo" and "Bar" seem to make in that scenario/feature. And that's also preferred while writing tests.
Generally, imho writing Cucumber tests is like placing yourself between a rock and a hard place. I noticed that developers tend to reuse and over reuse cucumber steps creating hard to understand and maintain scenarios.
The second approach requires more work in defining steps, butscenarios are cleaner and easier to read... BUT it requires more time to write a scenario as well as it produces a large steps definition base, which can be hard to maintain.
If you really want Cucumber for bdd then I would most prolly lean to 2nd option. Just make sure you'll use FactoryGirl or something similar under the hood, to create generic object and overwrite only what you need at a time.
I hope that you find this useful.
Related
The problem is basically in the header: I have some scenarios with 20-30 steps and Background is not usable. So how do I split those scenarios to several ones with 5-6 steps in one scenario,as cucumber best practice suggests.
Any tips? Someone did this already ? Any examples?
First of all you can look at the subject of the feature and instead of having a file for that you can have a folder.
Lets say you have a feature login, which has now gotten really big
features
|- login.feature
features
login
login.feature
Now you can start making files to extract scenarios too
features
login
| admin_login.feature
| normal_login.feature
| 2factor_login.feature
It should be fairly clear that you can keep on repeating this pattern.
As far as analysing your scenarios in your existing files. You can
analyse your scenarios by topic and group them together
look for things that break a common background, i.e. need a different method in the background or need a new method in the background
Each of these will give you candidates to extract into new files.
You just keep on repeating this until you have clarity in all your feature files.
I have some scenarios with too many parameters and most of the parameters causes the variation of scenarios. Therefore, I need to include parameter details in scenario name to give insight about the scenario. However, this causes too long Scenario lines.
For Example:
Scenario: Create list for Today's unique stuff of 'X' item with multiple string attribute values and 'distinct count' aggregation
Given I create a 'Create List' request and name as 'New List'
When I add 'X' item to 'Create List' request
And I add item attribute to current list query on list preview request
| attribute | operator | values |
| id | EXMATCH | id1,id2 |
And I add list aggregation to current list query on 'Create List' request
| aggField | aggType |
| stuff | DISTINCT_COUNT |
And I send request to 'Create List' request date as 'TODAY'
Then 'success' parameter in response should be true
And received list name should be equal to created list name
And received list queries in 'Create List' response should be equal to created list queries
Another Scenario:
Scenario: Create list for Today's unique stuff of 'X' item with multiple integer attribute values and 'sum' aggregation
Or:
Scenario: Create list for Today's unique stuff of 'X' item with multiple integer attribute values, 'sum' aggregation and <some other parameter related conditions which causes too long scenario name>
This can go on and on according to the number of different parameters who effects the scenario.
I have a feeling like there must be best practices writing clearer and shorter scenario names. Are there any?
How should I handle these long scenario names? Or, can I find easer/shorter way of express the content of scenario?
Cucumber allows you to use natural language (as opposed to a programming language) to write your scenarios. You can use all the tools of natural language to simplify your scenarios.
The two most powerful tools to simplify are
abstraction
naming
These tools work hand in hand. With abstraction you take something with alot of details and abstract it into something simpler that removes the details. You use naming to give this new thing a name. If your name is good you can know talk about your complex thing using your new simple term and no longer have to talk about the details.
To make you scenarios simpler you need to abstract, remove the details, and give things good names. The way to do this is to read your scenario and differentiate between WHAT you are doing and HOW you are doing it. Then have your scenarios focus on only saying WHAT they are doing and not saying anything about HOW they are doing it.
One additional tool when thinking about WHAT something is doing is to also think about WHY someone is doing the thing. So lets have a look at your scenario and formulate a few questions.
We do this all the time in computing. Every time we write a method/function we are abstracting and naming. We do this even more often in real life. When you order a coffee you don't say
"I'd like a double expresso in a warmed cup with 3oz of milk wet
foamed at 60C poured with a swan pattern"
You say
"I'd like a flat white"
And of course a double expresso is just another abstraction for a set of instructions that talks about water temperature, number of grammes of coffee, grind settings (extra fine), pressure of water etc. etc.
By using abstraction and naming we can talk eloquently about coffee with all its complexity without mentioning any of the details.
So what is the 'flat white' or 'double expresso' for your scenario?
Your scenario seems to be about creating some sort of a list.
WHAT sort of list is this?
WHY are you creating it?
WHAT will people use this list for?
WHY will people find this list useful?
Once you have asked and answered these questions you can start thinking about how to simplify. When you answer these questions, use the answers to
name your feature
describe your feature
write a preamble for your feature (the bit between Feature and the first Scenario)
write you Scenario titles
You shouldn't start writing a scenario until you have all of this done, and have a Feature that tells you WHAT your scenarios are going to be about and WHY its important for you to do these things.
You also talk about the parameters you are adding causing a variation in the scenarios. So for each parameter you are adding you should be asking
WHAT sort of variation does this parameter cause?
WHY is this variation important? Is it important enough to have its own scenario?
Again think about sets of parameters creating named things like a mocha, cortado or latte.
When you have answered these questions you can remove the parameters from your scenarios. Each set of parameters that creates a variation. For each variation you can remove the parameters by abstracting and giving a name to the variation
If you apply this approach and answer these questions then you transform your scenarios into something much simpler
I tried finding this solution but no luck. Its very simple requirement and I think cucumber has solution which I am not aware of.
I want to use same set of examples of scenario outlines to the multiple features. Every time I don't want to copy paste same set of example, it will lead to non-maintainability of feature files.
I tried with cucumber java with below example
Given The Economy is up for actions
When I make GET request to get **device** list with limit as <limit>
Then I should get success status as true
And I should get the **device** list with <limit> members
Examples:
| limit |
| 1 |
| 10 |
| 25 |
Given The Economy is up for actions
When I make GET request to get **user** list with limit as <limit>
Then I should get success status as true
And I should get the **user** list with <limit> members
Examples:
| limit |
| 1 |
| 10 |
| 25 |
Here you can see only When step is making difference, where in both steps limit examples are same. This is just an example, I have lot many cases like this in which I need to use different set of examples.
One thing which I love about testNG is data providers which will solve this problem easily. But looking forward to get similar in cucumber.
Cucumber does not provide such flexibility where we write examples/data tables only once in a feature file and access these in all other feature files.
Other side, if you do not use scenario outline in that case depending on data variation under examples lets say 3, you would have to write 3 different scenario.
If you are looking features similar to TestNG while using BDD/Gherkin, you should try pure TestNG implementation of BDD including gherkin. It is pure TestNG implementation for BDD provides all TestNG features including priority, dependency, listeners, parallel execution. It is designed for web, mobile and web-service functional test automation, providing design concepts and lots of inbuilt features required to support different use cases.
Refer
reusable-generic-examples-table-in-cucumber
examples-in-cucumber
customdataprovider-for-feature-file
creating-examples-for-scenariooutline-in-code
To share 'examples' data, you could store them in external static file (json/txt/what ever) and load them in particular steps implementation. I am not aware of out of the box solution in cucumber to share example between feature files.
I am trying to find out if there is a work around for my validation here. Have replaced actual steps with something similar.
Is it possible to define example tables ,, and pass the entire table as data to each iteration ?
I have huge list of sub elements to be verified and so I do not want to define sub element data in each iteration separated by a delimiter .
Here is the sample scenario
ScenarioOutLine: Validate POST call for XXX to have valid sub elements under each element
Given Request headers are set
When Request is posted
Then the response body content has element <ele_name> with sub elements <Sub_ele>
Examples:
|elem_name>|<Sub_ele>|
|Dept|{Dept_Sub_elements}|
|Subject|{Subject_Sub_elements}
|Course|{Course_Sub_elements}|
Examples:
|Dept_Sub_Elements|
|IT|
|Marketing|
Examples:
|Subject_Sub_Elements|
|Anatomy|
|Physciology|
|Management,economics|
I would hide all the mandatory verifications in the steps, in a method I always call after each scenario, and not pollute my feature files with it. The mandatory elements should always be there. They are not important when you discuss what the system actually does that the end users really care about.
BDD and Cucumber is all about communication and nothing about testing.
I always work hard on hiding the technical details I my scenarios as they need to be understood by the business representatives. Technical details belong among the steps or helper code that the steps delegate to. Your mandatory elements are a technical detail from my perspective.
You can use a DataTable after the desired Given, When, or Then step.
see reference: https://cucumber.io/docs/reference#data-tables
Depending on the language you are using you should be able to find the examples online. Here is an example of specflow:
Having Tables in Example Table in SpecFlow
If you have huge data tables (hundreds of rows) then you can think about saving the data in different file (property file, json file, or even excel file)
For smaller tables, they can be mentioned in .feature files. To make it easier to read, you can use table formatter plugins for intellij or eclipse.
e.g.
https://plugins.jetbrains.com/plugin/7550-pipe-table-formatter
Why not just use a single example table as an input to the validation step? Since nothing from the examples table is altering the given or when statements, there is no value to running this scenario multiple times.
Even if you were running it multiple times, I see no value to what you are trying to do, and it just makes it harder for humans to make any sense of the examples. Given the entire point of BDD is to have a conversation with stakeholders around the feature file and the scenarios there, anything which makes it harder for humans to understand the examples is generally a bad smell where BDD and Cucumber are concerned. Thus there is negative value in terms of trying to DRY out tables
Then the resulting page should have <Sub_element> found under <Element>:
| <Element> | <Sub_element> |
| Dept | IT |
| Dept | Marketing |
| Subject | Anatomy |
| Subject | Physciology |
| Subject | Management,Economics |
| Course | CompSci 210 |
| Course | Math 101 |
When writing scenarios, does anyone have a strong argument for choosing one of the following styles over another?
Feature: Search Product
As a customer
I want to search for a product
So that I can easily locate what I want to purchase
Scenario: Multiple Products Found (First Person Style)
Given the following products exist:
|Product |
|Normal Orange|
|Large Orange |
When I search for "orange" <---
Then the system should display the following products:
|Product |
|Normal Orange|
|Large Orange |
Or...
Scenario: Multiple Products Found (Generic Third Person Style)
Given the following products exist:
|Product |
|Normal Orange|
|Large Orange |
When the customer searches for "orange" <---
Then the system should display the following products:
|Product |
|Normal Orange|
|Large Orange |
Or...
Scenario: Multiple Products Found (Specific Person Style)
Given the following products exist:
|Product |
|Normal Orange|
|Large Orange |
When "John" searches for "orange" <---
Then the system should display the following products:
|Product |
|Normal Orange|
|Large Orange |
They all seem to work just fine - I wonder if I'm missing an obvious pitfall, as so many examples seem to use specific values for the actors (not just specific values for inputs / outcomes).
My only argument against using:
When the customer searches for "orange"
is that separate, equivalent steps would have to be defined if other actors could also use the same function.
Personally, I think "I" reads quite well (though I feel like I know otherwise). Thoughts?
It's fine either way, but there is a subtle difference.
I sometimes like to phrase things in the first person if the benefit of the outcome is for the user, and the third person if it's for someone other than the user.
For instance, you might have a story:
In order to prevent bots from spamming the site
As a moderator
I want users to prove that they are human.
And the associated scenario could either read:
Given a user is not registered
When they try to register
Then they should be presented with a CAPTCHA
When they fill in the CAPTCHA
Then they should be successfully registered
Or:
Given I am not registered
When I try to register
Then I should be presented... what, wait, no, I shouldn't!
In this instance, it's obvious that there's a cognitive disconnect with the idea that "I should be presented with a CAPTCHA", since they're annoying and nobody wants them. Putting this scenario in the third person makes it apparent that the benefit may not be for that person.
I occasionally make up names for the users - Ursula Usual for a normal user and Andy Admin for an admin, for instance. Using the third person this way can also be useful for calling out different personas and roles.
There are other scenarios in which the role is the same, but two different people play it.
Given Doctor Donald has filled out Priscilla Patient's prescriptions
When Doctor Diana looks for her file // <-- different doctor!
Then she should be able to find those prescriptions.
In the case in which other actors can use the same function, the context of their roles or permissions will be changing the behavior, and that context should be included in the scenario anyway, even if it's just implicit in their names.
I think as long as the story is clear to developers and non-developers like, I think I is fine to use. At the top you've already clarified that I am a customer. I don't think we care about which particular customer is doing the search.
I think it basically depends on the scenario.
If the scenario is one that will only ever involve customers, then "customer" is probably the most appropriate.
If a scenario may involve classes of users other than customers then the use of "John" (or "Jane", if you prefer) is more generic, and reduces the focus on just one class of user.
In general, systems are being built for somebody else to use, so while I agree that the first person ("I") style reads well, there are probably good psychological reasons for not using it.
Of course, I could be completely confused - I'm fairly new to BDD.