Writing BDD feature files shorter and cleaner - bdd

I have s lot of scenarios that are identical, they only differs by data which are passed to them.
This is example:
Feature: Linking facts from a report into Excel document
In order to link facts to an Excel document
As an user having access to report
I want to click on fact's value in the report
Scenario: Any uri item
Given I am logged as admin with admin
And I have selected Sample Project
And I have chosen to view report presentation view containing data from factcollection1 and all periods and all clients
When I click on excel cell C2
And I click on the value in 2 column of the row entitled any uri item
Then Excel cell C2 should contain value some internet address
Scenario: Base64 binary item
Given I am logged as admin with admin
And I have selected Sample Project
And I have chosen to view report presentation view containing data from factcollection1 and all periods and all clients
When I click on excel cell F3
And I click on the value in 2 column of the row entitled base64 binary item
Then Excel cell F3 should contain value asdf
Scenario: Boolean item
Given I am logged as admin with admin
And I have selected Sample Project
And I have chosen to view report presentation view containing data from factcollection1 and all periods and all clients
When I click on excel cell J3
And I click on the value in 2 column of the row entitled boolean item
Then Excel cell J3 should contain value true
I would like to shorten this to look something like following:
before scenario:
Given I am logged as admin with admin
And I have selected Sample Project
And I have chosen to view report presentation view containing data from factcollection1 and all periods and all clients
scenario:
When I click on excel cell XX
And I click on the value in YY column of the row entitled ZZ
Then Excel cell YY should contain value WW
and than some table data, like:
| XX | YY | ZZ | WW |
| C2 | 2 | any uri item | some internet address |
| F3 | 2 | base64 binary item | asdf |
| J3 | 2 | boolean item | true |
I found an solution.
There is an scenario outline with this ability.
Scenario Outline: display label in selected language
Given I am logged as <username> with <password>
And I have clicked on <button> button
Then result should be some result
Examples:
| username | password | button |
| john | doe | first |
| foo | bar | second |

You could use Scenario Outline instead of Scenario. Your example would look something like this:
Scenario Outline:
Given I am logged as admin with admin
And I have selected Sample Project
And I have chosen to view report presentation view containing data from factcollection1 and all periods and all clients
When I click on excel cell '<Cell>'
And I click on the value in '<Column>' column of the row entitled '<Row>'
Then Excel cell '<Cell>' should contain value '<CellValue>'
Examples:
| Cell | Column | Row | CellValue |
| C2 | 2 | any uri item | some internet address |
| F3 | 2 | base64 binary item | asdf |
| J3 | 2 | boolean item | true |

This is a very interesting question and I have spent some time researching what I call "data driven Specifications". This is partly inspired by the "row-test" or "data-driven-test" features that many common test frameworks offer.
Not that I use the terms "Scenario" and "Specification" synonmous, however I prefer the latter.
Similar to a normal unit test, a BDD specification is composed of three parts. A common template used is the "Given X When Y Then Z" formula. What you have discovered is that for a lot of your specifications the "X" part stays the same. Whenever I encounter such a situation, I try to create a Fixture class to abstract this. For example, one of those classes might be a LoggedInUserFixture which sets up a logged in user and makes it available to the test.
Very often, you'll find the need to compose this fixture with other fixtures, to create the setting for your specification. For example you may need a LoggedInUserFixture and a UserWithSampleProjectSelected for a single Specification. The easiest way to do this is to create another fixture class that will setup its child fixtures and makes them individually available to your test.
I am still resisting the urge to extract a common pattern for composing fixtures and make a test framework support this.
To come back to the suggestion to use data to drive specifications, I think it is a valid and useful patterns, I usually make the data drive my fixture creation (the fixture has an appropriate constructor for data injection then). See SubSpec's Theorie feature for details.

This answer is 8 years too late, but Gherkin has a way of eliminating this duplication. It's called the Scenario Background:
Feature: ...
In order to ...
As a ...
I want to ...
Background:
Given common step 1
And common step 2
Scenario: A
When ...
Then ...
Scenario: B
When ...
Then ...
More specifically applied to your situation:
Feature: Linking facts from a report into Excel document
In order to link facts to an Excel document
As an user having access to report
I want to click on fact's value in the report
Background:
Given I am logged as admin with admin
And I have selected Sample Project
And I have chosen to view report presentation view containing data from factcollection1 and all periods and all clients
Scenario: Any uri item
When I click on excel cell C2
And I click on the value in 2 column of the row entitled any uri item
Then Excel cell C2 should contain value some internet address
Scenario: Base64 binary item
When I click on excel cell F3
And I click on the value in 2 column of the row entitled base64 binary item
Then Excel cell F3 should contain value asdf
Scenario: Boolean item
When I click on excel cell J3
And I click on the value in 2 column of the row entitled boolean item
Then Excel cell J3 should contain value true
The three common Given steps are moved into the Background, and then each of your scenarios start out with a When.
Nice and tidy.
The reason this is preferable to a scenario outline is because you are dealing with parsing multiple kinds of data. Presumably there is some parsing logic behind the scenes, and parsing each data type could break in different ways during regression testing. Each test should only have one reason to fail, and your original scenarios properly capture that.

Related

Is there a way to remove 2 letters from a cell with a string (if they exist), and add a symbol on the end of the string?

I'm trying to code a google sheet to help develop a system to keep track of what training different people have. This is for an online role-playing game, to keep track of what spells/abilities different people have learnt. We've assigned different trainings a letter in the alphabet for ease of use. When someone has multiple trainings under a certain category, I want these to be able to combine to give a symbol rather than a letter. For example, if "A" and "T" are both related, I want them to be able to combine to give the "#" symbol.
It's a strange concept, I know, but this is the way our system has been built. I want to be able to have all people in the tracker sheet, then on a separate sheet, I want to be able to type their name in, and it will spit out their compressed training history.
The sheet's columns are formatted like so:
1. | A | B | C | D | E | F |... (Column)
2. |Name | Position | A | B | C | D |... (Header)
3. |John | Wizard | T | F | T | T |... (Data)
I've set up the main sheet, so that when I type their name, it uses the formula:
=JOIN("",
ARRAYFORMULA(
IF(
INDEX(Tracker!C:AB,MATCH(A2,Tracker!A:A,0),Tracker!C:AB),Tracker!C1:AB1,
)))
I've tried using regex extract/replace, however I'm not too good with regex, and I only want to replace characters with a symbol if BOTH exist, otherwise just leave it.
https://docs.google.com/spreadsheets/d/1cYGgmFJGGMtmwy6LF5k91H3-6UBVYIH_n8TIn1TU1Cw/edit?usp=sharing
Up there is a link to a sheet I just made, showing what I want to do. If anyone has suggestions, or questions, feel free to leave them here, or comment it on the spreadsheet.
Thank you in advance for any responses.
You may try below formula-
=REGEXREPLACE(JOIN("",FILTER(Tracker!C1:AB1,INDEX(Tracker!C2:AB,MATCH(A2,Tracker!A2:A,0)))),"[AT]","")&"#"
Here INDEX()/MATCH() will detect and return row based on name.
FILTER() will return characters based on selection of checkboxes of person row.
JOIN() will concat all characters in a single string.
Finally REGEXREPLACE(#,"[AT]","") will remove A & T.

Bitbucket Markdown - Add a Table to a Numbered List Item

I wish to add a table to a numbered list in bitbucket markdown.
Something like this:
1. Define the following role for the user:
|Role |Description |
|--- |--- |
|**UserRole** |The role is blah-blah |
2. Etc
I tried indenting by 4 spaces and 8 spaces. Neither shows the table as it should, but the 8 spacing at least shows the table as a pre-formatted table. What can be done to present the table as a proper table?
I solved distorted table rendering in a numbered list in Bitbucket by removing outside (most left and most right) vertical bars for all rows. The appearance of the table stayed unchanged.
Following your example:
1. Define the following role for the user:
Role |Description
--- |---
**UserRole** |The role is blah-blah
2. Etc
It appears that you have either encountered a bug or Bitbucket has intentionally disallowed such behavior. Unfortunately, Bitbucket's documentation regarding table support is extremely sparse. It consists solely of the following example:
| Day | Meal | Price |
| --------|---------|-------|
| Monday | pasta | $6 |
| Tuesday | chicken | $8 |
Rumor has it that Bitbucket uses Python-Markdown as their Markdown parser (full discloser: I am the developer of Python-Markdown). However, I have never seen any official confirmation of that. And which table extension they use is even less clear. As it happens, the table extension that comes with Python-Markdown parses your example just fine, which suggests they are using some custom extension.
I would suggest filing a bug report with Bitbucket.

Link tables and combine columns between them

My single dataset (generated from a large spreadsheet) is split into multiple tables. The relevant information is the dates and a numerical value assigned to them.
The data is organized as such on each table:
Start Date | End Date | Return Value
A1 | B1 | C1
A2 | B2 | C2
A3 | B2 | C3
The start and end dates are always quarter start and quarter end dates. The value C is always numeric. Each table represents a specific account. Some of these tables don't start until later dates (So Table 4 might have a start date equal to A3, for example).
I would like to group up these tables so the final report is organized as such:
Date range A1 - B1
Table1.C1 | calc(Table1.C1)
Table2.C1 | calc(Table2.C1)
Table3.C1 | calc(Table3.C1)
etc.
And on each detail line where TableX.CY is listed, perform relevant calculations using formulas.
The formulas I've already figured out and gotten sorted, but I'm lost at the best way to refer to each table without creating brand new formulas per table. IE, I don't want to create calcTable1(Table1.C1), calcTable2(Table2.C1), and so on, since there are over 40 tables in this.
How can I link these tables together so that the result set that CR is working with can be easily organized to produce this sort of report?
You can link tables in the Database Fields -> Database Expert -> Links tab.
If you wish to perform these calculations via SQL before they even reach the report, you can do so in the Database Expert by using the Add Command option to write your on SQL formulas.
Otherwise you want to group based on a date range. So you should probably first create a formula to return the format Date range A1 - B1. Then create a group based on that formula you just made.
To add a group, go to Insert -> Group and select your formula as the subject of the Grouped By field.

Drop-down list based on value on another cell in another sheet

I have searched for this question and found some useful tips but I can't seem to figure out the answers that they provide, so here's the scenario:
Top image: Sheet Name is Animals
Bottom Image: Sheet Name is Health
So the sheet Animals Column A (Owner) contains the data for dropdown list in sheet Health Column A (Owner).
What I want is in sheet Health if I choose CoopB (on dropdownlist Based on sheet Animals) I want the Column B (ETN) row 2 to become dropdownlist and the choices is based on the value of CoopB in sheet Animals.
Example: On sheet Health
| Column A (Owner) | ColumnB(ETN) |
|------------------|--------------|
| CoopB | CW-011110 |
| CoopC | CC-111101 |
| Coop1 | Coop1-0001 |
Note: on Sheet Animals Column C (Owner) value can be repeated, for example, we can expect CoopB value to appear repeatedly but on Column D (ETN) data are unique.
You can work similarly here, this time a Control sheet seems like a little less overkill.
Let's create a sheet called Control
In Control!A1 put "Owner"
In Control!A2 put =UNIQUE(Animals!C2:C)
In the data validation of Health!A2:A put the range Animals!A2:A
Now you can select the unique pet owners.
For a single Owner
For a single owner (in Health!A2) you could
In Control!B1 put "ETN"
In Control!B2 put FILTER(Animals!D2:D, Animals!C2:C = Health!A2)
For multiple Owners
For multiple owners we need to use the control sheet some more
In Control!B2 put =Health!A2:A so we have a mirror of our selections in Health
In Control!C2 put =IFERROR(TRANSPOSE(FILTER(Animals!D2:D, Animals!C2:C = B2)), "").
Drag the formula down however far you think you may need it (I could not get this to work with an Array formula)
Set the data validation in Animals!B2 to Control!C2:Z2, in Animals!B3 to Control!C3:Z3 etc.
You have to do this manually unless you want to write a script that fills in the data validation rules for you

Data Validation cell lock if value is true (Google Spreadsheet)

I am currently working now on creating data validation in google spreadsheet, and I want to lock a certain cell based on the value of the other cell in another spreadsheet.
Scenario: (Based on the Image)
There are 2 different spreadsheets (Sample1 & Sample 2) with has the same column H which is Status and the same Cell H2 which is Dropdown list (Active and Inactive).
on Sample1 Cell H2, If I choose Inactive, I want the Sample2 Cell H2 to be locked, otherwise if on Sample1 Cell H2 If I choose Active, the Sample2 Cell H2 should be remain as dropdown list.
Thanks in advance.
I assume you don't want to lock the cell as in protecting it.
You can't remove the data validation but you can give it an empty set.
The easiest approach for this kind of thing is to add a Control sheet that handles this.
It may be a bit overkill for this application but you could create proper interactive menus in this fashion that are more complex and contain more options on the dependent and the independent side.
____A_________B_________C____
1| Active| Inactive| Current|
2| Active| | |
3| Inactive| | |
With cell C2 getting the formula
=INDEX(A2:B3, , MATCH(Sample1!H2, A1:B1, 0))
And the Data validation in Sample2!H2 referring to Control!C2:C3

Resources