When writing a BDD feature, should I put previous user interaction into a Given step, or a When step? - bdd

I am trying to write requirements for a multi-step business process (via a wizard). I have many scenarios where user interactions with one screen will change whether you are allowed to pick options on another screen.
For example (I've obscured the actual business, but the process and form of the steps is nearly identical):
Feature: Personal Diagnostic Search Filter
In order to select a Technician who offers Personal Diagnostics,
when I've asked for a Personal Diagnostic
As a Business Customer
I want to limit my search to Technicians who offer Personal Diagnostics
Background:
Given a Business named "Big Al's Auto Supply"
And a Customer named "Bob Test" at the "Big Al's Auto Supply" Business
And an Account named "bobtest#testbusiness.com" owned by "Bob Test"
And the "bobtest#testbusiness.com" Account has the "Repair Order Creator"
permission
And you log in as "bobtest#testbusiness.com"
And you start scheduling a new Repair Order
Scenario: Enter the Select Technician page when Use PD is selected
Given you select Use PD
When you enter the Select Technician page
Then the PD Filter should be visible
And the PD Filter should be selected
Scenario: Basic Search for Technicians when PD Filter is selected
Given a Technician named "PD Technician"
And the Technician named "PD Technician" supports PD
And a Technician named "Non-PD Technician"
And the Technician named "Non-PD Technician" does not support PD
And you select Use PD
And you enter the Select Technician page
And you select the PD Filter
And you select Basic Search
When you search for Technicians with the name "Technician"
Then your search results should contain "PD Technician"
And your search results should not contain "Non-PD Technician"
But on the Gherkin wiki, it is recommended that you:
Avoid talking about user interaction in givens
They go on to make an exception, though:
Log in a user (An exception to the no-interaction recommendation. Things that “happened earlier” are ok).
It also is said on that page that:
The purpose of When steps is to describe the key action the user performs
What belongs in a Given and what belongs in a When if you have a lot of UI interaction?
In my first scenario, select Use PD requires UI interaction, as it is part of the wizard for creating a new Repair Order. However it is a precondition for PD Filter to be visible, and is triggered when the user enters the Select Technician page.
The first scenario might not be so bad, but the second scenario exacerbates the problem. The search is triggered when you hit Search but there are a lot of UI interactions that must be done to navigate to that page. Some of those interactions can't be glossed over, either, as Use PD must be selected for the search filter to even appear. But those UI interactions aren't the key action of the scenario.

As a general rule, try as much as possible to phrase the scenario as if you're having a conversation about it, and exclude as much irrelevant information as possible.
For instance, I would love your scenarios above to read something like:
Given our customer Bob Test is scheduling a repair order
And we have two technicians: "Fred Technician" and "George Nontechnician"
When Bob Test decides he wants a Personal Diagnostic
And he selects a technician
Then the search results should only contain "Fred Technician"
Then do whatever is necessary to make those steps work - be they logging in or otherwise. Notice I haven't talked about "pages", or taken the actual steps - they should be intuitive for the user. BDD isn't about testing. It's about coming up with examples of how people are going to use the system, so that you can have conversations around those examples and explore them, find exceptions and different scenarios, etc.
Checking that the filter is visible is not valuable. The user doesn't care that the filter is visible. He cares that he can use the filter to get his results, so just do that.
In the code, I usually pass a "World" object between my steps. That can get a lot of the gubbins out of the way. I haven't used Gherkin much but I imagine it provides for a similar ability. You can store all the user details in there, which technicians you've created so that you can check it doesn't bring back "George Nontechnician" in the results, etc.
Using friendly names for roles is useful too, because people can then imagine what Fred and George look like.
Get rid of anything which isn't going to make a difference in the scenario and isn't going to help people imagine it happening. You know that Bob has permission to schedule an order because that's what he's doing - just add the necessary stuff to that step.
The "When" is the behavior you're interested in describing. In this case, you're interested in the ability to filter for Personal Diagnostics, so all the user interaction associated with behavior should be in the "When", and all previous interaction should be in the "Givens". I find it useful to try and think of a context in which the outcome is different - for instance, what happens if there are no PD technicians available? That tells me what the difference is; we'll be setting up a different context but performing the same event. Context goes in the Given, events go in the When. (This used to be much simpler before "Background" was introduced).
In general, if your eyes glaze over when you look at a scenario, you're doing something wrong.
Hope this helps.

Related

Trying to create a custom process that shares specific information

I work for a high school that has a regular four day school week and calls students in for "Reteach and Enrichment" on Fridays. To help organize the schedule for this, the school has created a Google Sheet that lists all of the student names and allows the teachers to fill in what time they would like any particular student to come to their class that Friday. This is working fine for the school's organizational side, but informing students of their assignments is currently a bit of a nightmare.
Because students will try to get out of anything, we have to have documentation indicating that we "told the students they need to come to our classroom on Friday". This is currently done in the form of giving a student a slip of carbon copy paper informing them of the time they are called in. As you can imagine, this is extremely time-consuming and full of holes since the students can throw the paper away or claim "they never got the paper" even though we've got a second copy of that paper indicating that it was filled out. But I digress.
The reason I'm writing to you fellow internet people is that I've taken on the task of trying to streamline the process of notifying the students of their schedules for Fridays. Because of privacy issues, we cannot give the students read-only access to the master list for Fridays, but I'm looking for a way to inform them of their specific information. My first thought was to write a program that would make a google sheet of each line on the master sheet, and share that sheet with the student whose information was on that line. This seems painful to set up and manage though and will lead to a lot of documents in google drives that are only needed for a week. The second problem is that I'm not sure what type of application I could use to run a program that would need to be able to access one google sheet, copy information from it, create a new google sheet, paste the copied information, gather the correct account the information needs to be shared with, and share read access to the new sheet that was created. I was thinking of using Auto Hotkey, but I know there's got to be a better solution to this problem.
If you have any suggestions for a different approach, please let me know. I believe that I can get an automated process to do what I described above if I can get the process down to a rote set of steps to take for each line on the original google sheet. But I'm hoping there's a way to do like an XLookup or Vlookup from a new sheet that references the original or something.

How do describe a simple process in Gherkin-style? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Suppose I'm designing some SaaS service. And I need to have a function that allow users create sites. User can makes special settings for each site in the admin panel (e.g. design of widget) and gets unique code for install service to his own site.
User story could be:
As a logged user I want to add the new site in the admin panel so that I could configure each instance of widgets separately and could get a unique code for install widget to my own site.
Form
But if I will try to describe this functionality with BDD or GWT (Given When Then) or Gherkin-style, I will face with some trouble. I start from next description:
GIVEN I'm logged into admin panel
AND I'm on "Sites" page
WHEN I click "Add site" button
THEN Pop-up window "Add site" come up
As you can see above realization suppose that site adding will be in pop-up window (e.g. it very important for UX). Pop-up window contains Site URL input field, drop-down control with languages and "Add" and "Cancel" buttons.
And we got a strange scenario which responsible for just pop-up opening. Is it correct? And how can I name this scenario ("Add site's form opening" ??)? Also this scenario has only a one case (when I click - pop-up open). Maybe this scenario not needed at all? I'm confused...
In this case we need to create another scenario when describes:
GIVEN "Add site" pop-up form is opened
WHEN I fill the "Site URL" field
AND click on "Add" button
THEN New site will be create in system
AND I will transfer to my own site's list
How do you think, where do I need to apply a business rules such as:
1) When new site is created a unique code must be generated and consist of minimum 8 characters including numbers and Alphabetical symbols.
2) checks doesn't apply for Site URL input field and user can input a Cyrillic symbols
3) etc?
I have a lot of additional question and hope on the community help!
The thing with BDD is to stay away from implementation details as much as possible. This scenario has multiple implementation details:
GIVEN I'm logged into admin panel AND I'm on "Sites" page
WHEN I click "Add site" button
THEN Pop-up window "Add site" come up
What happens if the "Sites" page becomes "Awesome Site" page or is simply deleted?
What happens if "Add site" is not a button anymore?
What happens if it's not a popup but a redirect occuring
What happens after? Is the value simply in showing the popup? I guess not...
For this specific example, a better approach would be:
GIVEN I'm an authorised administrator
WHEN I enter all the required information for a new site and save it
THEN I should see that site in my own sites list
With this scenario, if your implementation changes, you will only have to change your step definitions, you won't have to change your gherkin. Don't forget that those tests are supposed to explain the Behaviour of the system, not the way it is implemented.
The other questions you have are more related to unit testing in my opinion:
When new site is created a unique code must be generated and
consist of minimum 8 characters including numbers and Alphabetical
symbols => I'd do it at the class level, gherkin would not be
appropriate unless the customer specifically asked for this, then
the condition is "THEN a code having the required characteristics is
generated for that site" and you would have to define "required
characteristics" in a glossary the customer can read and understand.
Checks doesn't apply for Site URL input field and user can input a Cyrillic symbols => again, would put that at the class level en same as for 1. unless the customer wants to be able to read something about it, it should be at the unit level.
I hope that answers your question. I recommend this article by Dan North if you want to have a better idea of how to write better gherkin features.
EDIT 11/13/14
Based on your comments, I suggest we take a step back and describe a way to deal with requirements in your case. I have to tell you that I'm not a BDD expert and am only sharing my own personal experience, for more info on the subject I suggest you get in touch with the guys behind BDD Kickstart and Cucumber.pro where you will find online BDD courses. They will be able to give you lots of information and books to read.
That being said, let's dive into the subject.
The first thing you get is a list of features or stories that, if you follow Mike Cohn's story template would look like:
As a <type of user> I want <to do something> in order to <serve a business purpose>
I personally like to put the business purpose first to make sure we don't skip it in the discussions. You might also not follow that template and that's fine, but remember that it's a good idea to make sure the features you are listing with your customers have a business purpose. If there is no business value behind a feature then what's the point of doing it anyway...
So you do have a list of features/stories described as above. Now for each of these features, there are different cases or scenarios, that's what Dan describes in his article. This is where the Given-When-Then is introduced.
Scenario: Title
Given <some context>
When <there is an event>
Then <something happens>
Each of those scenarios are examples on how this specific feature behaves in different contexts. They are the different acceptance criteria for a specific feature, things the customer described as the expected behaviour of the system. They should be ignorant of any implementation details. So stuff like:
Given I am on page "First page"
When I click "Hello world"
Then I should see "You clicked hello world"
Is wrong for the reasons described prior to this edit.
Let's assume the following feature:
In order to save time when answering clients requests, as a webmaster,
I want to be able to manage the list of websites I am responsible for
Scenarios for this story would be:
Scenario 1: Show a list of websites
GIVEN I am an authorised administrator
AND I am managing several websites
THEN I should see a list of all the sites I manage
Scenario 2: Add website to list
GIVEN I am an authorised administrator
WHEN I enter all the required information for a new site and save it
THEN I should see that site in my own sites list
Scenario 3: Edit website from list
GIVEN I am an authorised administrator
WHEN I edit the site informations
THEN I the changes should be visible in my sites list
...
Now what if you want to go into data validation stuff like "site should have a title" for instance. To me there are two different ways to approach this. You can test that from the user's perspective with a full-stack test or test that there is some validation at the object level.
Let's assume the following scenario:
Scenario: New site has no title
GIVEN I'm an authorised administrator
WHEN I forget to fill in the title for a new site and save it
THEN I should be warned the site is not valid
You can use cucumber or specflow to run this scenario from the UX, therefore using some kind of browse-based proxy to test your app. That is usually slow as it hits the whole system and simulates a real user. It's an option, but I don't think it's the best though. IMO not all tests should be run against the UX and having too many Gherkin features can be a pain to maintain, that's why I prefer focusing on having the happy or critical path (usually I ask myself, where does the money comes from) tested full-stack and put the rest at lower levels.
You can still use Gherkin for these unit tests if you'd like. But that is not mandatory. You only need a way to show your customer you actually have a test for all those specific format controls and validation checks.
That doesn't mean you are not doing BDD anymore, you can still use the given-when-then-should pattern in rspec if you're a rubyist, or any other testing framework you use.
Hope that clarifies all this, let me know if there are any confusing parts...
I think Marc simply deserves the big green tick on this one, thanks to his amazingly thorough answer!
I just wanted to add a few comments.
You don't need to automate all your scenarios.
If you want to capture business requirements in a form that everyone (i.e. including non-tech savvy folks) can understand and Gherkin's Given/When/Then work for you, just go for it. There's nothing forcing you to automate all of your scenarios.
You don't need to automate all your scenarios through the UI.
Your software is made of layers that often respond to similar behaviours, via different interfaces (UI, HTTP, API, ...). Should you want to describe fine-grained business rules (i.e. site name constraints) with automated gherkin scenarios, you could write step definitions that talk directly to your domain layer instead of going through the user interface. That would probably still give you a decent level of confidence.
As a side note, I would recommend not to use Given/When/Then in classic testing frameworks (i.e. those that only devs can see!) if your purpose is to share your tests/requirements with non-tech people.
Have conversations!
Above all, BDD is about better communication: try to talk more, involve your developers (or some of them) earlier in the process so that they gain more knowledge, sooner. Formalising Gherkin scenarios comes in a second phase. Automating them should even be further down your priority list!

Creating meaningful user stories

We are trying to use BDD to create a web service to supply data to a web page and then save the user's changes.
The story I have so far goes
Given I want the data for order number 1234
When I load the data
Then I have the data for order number 1234
What am I missing in my approach?
Are user stories not appropriate for this kind of task?
How do I go about formulating meaningful user stories?
[Update]
As a customer
I want to see my order
So that I can check it is what I expect
Given I have entered the order number
When I Click GO
Then I should see my order displayed on the screen
Here's how I'd write what you have so far:
Feature:
As a customer
I want to be able to view and change my orders
So that I can check that they're being processed as I expect and deal with them if they're not
Scenario:
Given I am a customer
And I have an order
When I go to the order
Then I should see the order
(I indented the way my tools seem to want me indent Cucumber, which is what I use, but that's not important.)
Here are at least some of the reasons why I'd rewrite it that way:
It is usual for several Scenarios that have to do with the same product feature (order management in this case) to be in the same Feature file, so the Feature section should have a broader scope than a single Scenario. Maybe this Feature should even include placing orders in the first place.
Givens are things that are true before the time period that the scenario is about, like the existence of the customer and the order. Actions during the scenario belong in Whens.
It's good to avoid UI detail like "click" and specific button names and "displayed on the screen". The scenario should focus on behavior. The When I go to the order step can encapsulate the details of going to the screen where you enter the number, entering the number, and clicking the button.
Likewise, all of the checks for different fields of the order that should be visible can be encapsulated in Then I should see the order.
I said "the order" rather than "my order" because And I have an order establishes that there's a single order with a special relationship with the scenario, and it's good to establish a language across all your scenarios that makes that relationship clear -- I always use "the" in that case. (This is a very small point.)
With those stylistic points taken care of, this is an OK scenario and I've certainly written many similar ones. To get to your real question, however:
Where Specflow-type tools really shine is when you use them to describe as complete a use case/user story as you can. For example:
Scenario:
Given I am a customer
And there is a product
When I go to the product page
Then I should see the product
When I add the product to my cart
And I check out
Then I should see that the order has been placed
And I should receive an order confirmation email
When I go to my orders
Then I should see the order listed
When I go to the order
Then I should see the order
When I cancel the order
Then I should see that the order has been cancelled
And I should receive an order cancellation email
When I go to my orders
Then I should not see the order listed
This is more valuable as an acceptance test, because it captures more requirements, and it's more powerful as an integration test, because it exercises more of the system, and fakes less of it. (In the short scenario we had to create an order artificially. Here we're doing it through the system.)

Is it possible to write a TFS Shared Query with a parameter on a custom field?

I have a set of queries on the Team home page that use the standard #Me, for example to let different users quickly get to bugs they have personally raised, PBIs they created that are now in a certain state.
The users are in customer groups and I'd like to have a similar set of queries showing as tiles on the home page, e.g. "Team Open Bugs", "Team PBIs for review".
Is it possible to write a query that does this -
Select all [work item type] from [team project] where [state] and [#myCustomerTeam] ?
From what I have read so far I believe this is not possible, and certainly not possible through the UI. I'm curious to find out if anyone has solved a problem like this - having different customer groups see different Team Favorites tiles on the Home page of Team Web Access - in some other way. I'm going to try making three sets of queries and putting different permissions on them (there are TFS groups that correspond to the Customer Group field) but I'm not confident that Denying even Read permission on the query itself will stop the tile showing on everyone's homepage.
Edited to say that solution worked for my purposes, as per comment.
Still interested to know if anyone has managed something like this more cleanly. In this case the field I would have liked to parameterise happened to be something I could map to a completely different type of thing, thus shifting the problem. I can imagine wanting to parameterise a field that didn't have that characteristic though.

Create an internal message system with Rails

I have Users that can create DinnerEvent that contain Food. User specify preferred Food using a join table. Would like to create an internal message system that automatically sends out a notice to other Users who "prefer" the Food in the DinnerEvent that was created. Can anyone provide some guidance as to how I can go about approaching this or if there are any good reference resources out there (haven't had much luck searching)? Thought about ActiveMailer but decided I wouldn't want people to get spammed all the time in their email inbox. Would prefer to only use Rails to achieve this.
There's a lot of options here and many use cases to think through. Maybe you can start with something very simple that:
Tracks the last date/time of login for each user
On some page (specific to the logged in user), display all DinnerEvents created since last login that match their Food preferences. Should be simple Active Record to pull this.
Continue to show this list until they dismiss it (record this date/time) or login again
A full blown messaging system will probably require more complex stuff like queues for each user that are subscribed to a master queue. And, possibly an additional backend data store like Redis. I'm purposefully leaving out the details of something like this for now; it's a much bigger topic.

Resources