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.
Related
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 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 |
So I've been using specflow for a while now and something has been bugging me.
This is an example of a scenario we are currently using:
Scenario: Select a region via selection button
When I select "Scotland" from Available Regions
And I click on the "Select One" button
Then Available Regions does not contain "Scotland"
And Selected Regions contains "Scotland"
Is there a away to avoid saying "Scotland" on almost every line ?
Or does it make it more readable and I should just stick with it ?
Before I attempt to answer your question, can I suggest you take a minute to go and read Dan North's Who's domain is it anyway.
So firstly I'd like to get rid of the line that says And I click on the "Select One" button, because I think that should implicitly be part of When I select "Scotland" from Available regions.
Now you have
Scenario: Select a region
When I select "Scotland" from Available Regions
Then Available Regions does not contain "Scotland"
And Selected Regions contains "Scotland"
And you could write it as
Scenario: Select a region
When I select "Scotland" from Available Regions
Then Available Regions does not contain the last selected region
And Selected Regions contains the last selected region
Is there much of a difference? Well probably not.
What I've found as I've spent more time with cucumber, is that it helps to refactor your scenarios as much as you refactor the code behind them. In C#/SpecFlow we could implement
Then Available Regions does not contain "Scotland"
with
[Then("Available Regions does not contain (.*)")]
public void ThenAvailableRegionsDoesNotContain(string region)
{
AvailableRegions.Contains(region).ShouldBeFalse();
}
and
Then Available Regions does not contain the last selected region
with
[Then("Available Regions does not contain the last selected region")]
public void ThenAvailableRegionsDoesNotContainLastSelectedRegion()
{
ThenAvailableRegionsDoesNotContain(LastSelectedRegion);
}
It honestly is up to you. Which dialect you prefer
Interesting example!
As others have stated, it's generally advised to avoid details of implementation in your scenarios - that's what the step definitions are for. But you know this already.
The question I'd then ask is: who are you proving this behaviour to? Who is interested in asserting that you can click a button or double click by means of a formal test? If your answer isn't "nobody", then perhaps this applies:
"When this scenario was written, you can imagine the stakeholder probably didn’t care much how ... As soon as we start introducing options ... the details ... suddenly become interesting ...
At this point I would expect this scenario to be augmented with some finer-grained, or lower-level, scenarios, each describing the different [options] we support. These new scenarios would be aimed at a different stakeholder."
From the comments on Dan North's "Whose Domain Is It Anyway?"
Perhaps you want the scenario written in both forms: one higher-level just demonstrating that the user can select the region for the business guys (how doesn't matter) and another two, for a different stakeholder showing the different options to do so.
So, once you've decided that what you're doing is worthwhile, I'd probably just repeat "Scotland" (a table for a single value is overkill here).
On a slightly different note, I also suggest:
Then Available Regions should not contain "Scotland"
And Selected Regions should contain "Scotland"
I'd recommend revising the title of this scenario. "Select a region" is not really telling you, what to expect from this example. It could be some complex behaviour that is triggered when you select a region, or a tiny UI detail such as the selected region moves from the available regions to the selected regions list.
If I understand your example correctly, it's the latter, so I'd suggest a title like:
Scenario: Selected region should be moved from available to selected regions
Having a more expressive title has IMHO to advantages:
1) You can quicker navigate and find relevant examples in your living documentation, when you are looking for a certain detail: reading an expressive title is always faster than reading the whole example and reverse engineering the intention of it.
2) For more complex scenarios (which this example seems not to be), an expressive title conveying the intention of the scenario helps the reader understanding the details of the scenario more quickly.
To make the scenario more interesting to read, I would combine the assertions into one step, as you actually want to assert that the selected item has been moved from the available to the selected list:
Scenario: Selected region should be moved from available to selected regions
When I select "Scotland" from "Available Regions"
Then "Scotland" should be moved from "Available Regions" to "Selected Regions"
I think this is pretty near to how I would explain this detail to somebody in a conversation. I wouldn't mind repeating "Scotland" here, although some people might prefer replacing "Scotland" with "the selected region", as AlSki already pointed out. It's a matter of taste and I usually try to listen what actual words were used during the conversation about the scenario, that should happen always before writing it down.
As a minor note I want to mention that I have the impression that this is a scenario concerning a pretty low-level UI detail. I would be much more interested, what higher level impact it has, when I select a specific region (if selecting a region has any specific business relevance at all). And if you really want to describe and automate validation of such a low-level UI detail in a scenario, I'd consider showing this also in how I phrase the scenario:
Scenario: Selected region should be moved from available to selected regions list
When I select "Scotland" from the "Available Regions" list
Then "Scotland" should be moved from the "Available Regions" to "Selected Regions" list
Of course I just assumed now, that you are describing a detail UI behaviour of a list in your scenario, as you didn't write about a list in your original scenario. If it is not about the UI, what you are describing, the scenario should be phrased differently to express this better.
While I agree with #AlSki that some refactoring is a good idea, you can use the Examples syntax to use the same value multiple times:
Scenario Outline: Select a region
Given do this "<value>"
And do that "<value>"
When we perform "<value>"
Then we get "<value>"
Examples:
| value |
| Scotland |
You can also add multiple entries into the table to run the same test many times with different values each time:
...
Examples:
| value |
| Scotland |
| England |
| Wales |
Here is an example with multiple values, which allows you to do things like:
Scenario Outline: Select a region
Given do this "<value>" with "<area>"
And do that "<value>"
When we perform "<value>"
Then we get "<result>"
Examples:
| value | area | result |
| Scotland | North | 40 |
| Scotland | South | 100 |
| England | West | 200 |
| England | North | 180 |
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.
I am designing an autosuggest feature on a quick-search box. Suggestions will include small icons, multiline text, etc. The application is handling orders. The search field will recognize a variety of different meaningful terms - e.g. customer surname, order id, etc. But when an order ID is input, I want users to get an opportunity to view either the order, or the person. I was thinking that I would like a hierarchy within the list - so if i type 1234, and it matches 5 orders for 3 different people, the 3 people are returned at the top level, and their 5 orders underneath the respective customer.
Quick mockup:
Has anyone seen something like this implemented elsewhere? Don't want to re-invent the wheel. Also interested in any other feedback.
Answer to your question: No, haven't seen this elsewhere.
Feedback on your mockup:
I would say that it is a pretty creative autosuggest solution.
However, I think it is overkill though. If I just want to quickly navigate to the Order page by searching a specific Order ID (and expecting only one result in the autosuggest), but the autosuggest shows up five order items under three people (as shown in your mockup), I think that is way too much, put aside performance.
My idea:
Each autosuggest item contains one Primary Line that can clearly identify the item and additional Details Line(s) that provide more description about the item, similar to Google's search result page and Facebook search autosuggest.
For example, the autosuggest shows up each item like this when users search for an order:
(Order Icon) 23-34534
Loaf of Bread, Soda and more.
By Bob Jones, Paul Smith and others.
You can make each order item (Loaf of Bread, Soda, more) link to the respective order item line in the Order page, and each person name to the respective person page. This method is more concise and takes less space than your mockup while still providing the functionality that you want.
Sometimes, simple is better, less is more. Remember the KISS principle. Think of Apple iPod and iPhone as examples.