Specflow Feature-level Templates - specflow

I'm trying to execute an entire SpecFlow Feature using three different UserID/Password combinations. I'm struggling to find a way to do this in the .feature file without having to introduce any loops in the MSTest.
On the Scenario level I'm doing this:
Scenario Template: Verify the addition functionality
Given the value <x>
And the value <y>
When I add the values together
Then the result should be <z>
Examples:
|x|y|z|
|1|2|3|
|2|2|4|
|2|3|5|
Is there a way to do a similar table at the feature level that will cause the entire feature to be executed for each row in the table?
Is there other functionality available to do the same thing?

I don't think the snippet you have is working is it? I've updated the below with the corrections I think you need (as Fresh also points out) and a couple of possible improvements.
With this snippet, you'll see that the scenario is run for each line in the table of examples. So, the first test will connect with 'Bob' and 'password', ask your tool to add 1 and 2 and check that the answer is 3.
I've also added an ID column - that is optional but I find it much easier to read the results with an ID number.
Scenario Outline: Verify the addition functionality
Given I am connecting with <username> and <password>
When I add <x> and <y> together
Then the result should be <total>
Examples:
| ID | username | password | x | y | total |
| 1 | Bob | password | 1 | 2 | 3 |
| 2 | Helen | Hello123 | 1 | 2 | 3 |
| 3 | Dave | pa£sword | 1 | 2 | 3 |
| 4 | Bob | password | 2 | 3 | 5 |
| 5 | Helen | Hello123 | 2 | 3 | 5 |
| 6 | Dave | pa£sword | 2 | 3 | 5 |
| 7 | Bob | password | 2 | 2 | 4 |
| 8 | Helen | Hello123 | 2 | 2 | 4 |
| 9 | Dave | pa£sword | 2 | 2 | 4 |

"Is there a way to do a similar table at the feature level that will
cause the entire feature to be executed for each row in the table?"
No, Specflow (and indeed the Gherkin language) doesn't have a concept of a "Feature Outline" i.e. a way of specifying a collection of features which should be run in their entirety.
You could possibly achiever what you are looking for by making use of Specflow tags to tag related scenarios. You could then use your test runner to trigger the testing of all the scenarios with that tag e.g.
#related
Scenario: A
Given ...etc...
#related
Scenario: B
Given ...etc.

SpecFlow+ Runner (aka SpecRun, http://www.specflow.org/plus/), provides infrastructure (called test targets) to be able to run the same test suite (or selected scenarios) with different settings. With this you can solve problems like the one you have mentioned. It can be also used to run the same web tests with different browsers, etc. Check this screencast for details: http://www.youtube.com/watch?v=RZYV4Dvhw3w

Related

BDD how can i write a table if I have more than one variable in Given conditions

Below id my scenario that I am trying to automate:
Scenario Outline: create an invoice selecting
Given following <payment_term> is selected
And following <delivery_terms> is selected
And following <verzenderijnr> is selected
Examples:
| payment_term | delivery_terms | verzenderijnr |
| 1 | 1 | 1 |
| 2 | 2 | 2 |
When i transition the document to "final_invoice"
Then i expect the following transaction in my administration:
Examples:
| journal.id | account.id | document_date | due_date |
| VRK1 | 10016 | "2018-12-17" | 2019-01-24 |
You should use example with "scenario outline" and not only with scenario.
also, Example table should come at end after all "Given When Then" statement.
I'm not 100% sure what you're trying to accomplish exactly, but wouldn't your scenario be more easier to read if done like this?
Scenario Outline: Determine due date for sales invoices
Given I am creating a sales invoice on <Invoice date>
When I should <Pay within days>
Then the <Due date> should be correct
Examples:
| Invoice date | Pay within days | Due date |
| 2018-12-18 | 5 | 2018-12-23 |
| 2018-12-29 | 5 | 2019-01-02 |

Behave - Common features between applications, avoiding duplication

I have many applications which I want to test, which have a largely overlapping set of features. Here is an oversimplified example of a scenario I might have:
Given <name> is playing a game,
When they shoot at a <color> target
Then they should <event>
Examples:
| name | color | event |
| Alice | red | hit |
| Alice | blue | miss |
| Bob | red | miss |
| Bob | blue | hit |
| Bob | green | hit |
It's a silly example, but suppose really I have a lot of players with different hit/miss conditions, and I want to run just the scenarios for a given name? Say, I only want to run the tests for Alice. There's still advantage to having all the hit/miss tests in a single Scenario Outline (since, after all, they're all closely related).
One approach would be to just duplicate the test for every name and tag them, so something like:
#Alice
Given Alice is playing a game
When she shoots at a <color> target
Then she should <event>
Examples:
| color | event |
| red | hit |
| blue | miss |
This way I can run behave --tags #Alice, But then I'm repeated the same scenario for every user, and that's a lot of duplication. Is there a good way to still compress all the examples into one scenario - but only selectively run some of them? What's the right approach here?
Version 1.2.5 introduced better ways to distinguish scenario outlines. It is now possible to uniquely distinguish them and thus select a unique scenario generated from an outline with --name= at the command line. For instance, suppose the following feature file:
Feature: test
Scenario Outline: test
Given <name> is playing a game,
When they shoot at a <color> target
Then they should <event>
Examples:
| name | color | event |
| Alice | red | hit |
| Alice | blue | miss |
| Bob | red | miss |
| Bob | blue | hit |
| Bob | green | hit |
Let's say I want to run only the test for Bob, red, miss. It is in the first table, 3rd row. So:
behave --name="#1.3"
will select this test. In version 1.2.5 and subsequent versions. A generated scenario gets a name which includes "#<table number>.<row number>" where <table number> is the number of the table (starting from 1) and <row number> is the number of the row.
This won't easily allow you to select all scenarios that pertain to a single user. However, you can achieve it in another way. You can split your examples in two:
Examples: Alice
| name | color | event |
| Alice | red | hit |
| Alice | blue | miss |
Examples: Bob
| name | color | event |
| Bob | red | miss |
| Bob | blue | hit |
| Bob | green | hit |
The table names will appear in the generated scenario names and you could ask behave to run all the tests associated with one table:
behave --name="Alice"
I do not know of a way to access the example name in steps and thus get rid of the first column.
The full set of details is in the release notes for 1.2.5.

cucumber table diff regardless row order

is there any way to tell a cucumber table's diff! method, that I don't care about the row order?
Example:
The feature says:
| start | eat | left |
| 12 | 5 | 7 |
| 20 | 5 | 15 |
The code outputs
| start | eat | left |
| 20 | 5 | 15 |
| 12 | 5 | 7 |
which is ok for me. Cucumber would fail nonetheless, because it also checks for the order (which is nice in most cases).
Couldn't find a solution for it :(
Maybe you can sort the rows in both tables (the test value and the tested value) in a way ensuring a unique order.
I would have expected that there is a corresponding ruby version of the following Java method:
cucumber.api.DataTable#unorderedDiff(cucumber.api.DataTable)
This is under cucumber-core artifact.

Can I have a cucumber example with several values in a single column x row position

Hi here is what I what I have:
Scenario Outline: Seatching for stuff
Given that the following simple things exists:
| id | title | description | temp |
| 1 | First title | First description | low |
| 2 | Second title | Second description with öl | Medium |
| 3 | Third title | Third description | High |
| 11 | A title with number 2 | can searching numbers find this 2 | Exreme |
When I search for <criteria>
Then I should get <result>
And I should not get <excluded>
Examples
|criteria|results | excluded |
| 1 | 1 | 2,3,11 |
| 11 | 11 | 1,2,3 |
| title | 1,2,3 | 11 |
| öl | 2 | 1,3,11 |
| Fir* | 1 | 2,3,11 |
| third | 3 | 1,2,11 |
| High | 3 | 1,2,11 |
As you can see I'm trying to test a search field for a web-application using cucumber and the scenario outline structure in order to test several search criteria.
I'm not sure how to handle the input I would get as result and excluded in my steps.
Maybe this doesn't work at all?
Is there a workaround?
There's nothing wrong with what you're doing. Cucumber will just take that as a single string. The fact that it's actually comma-separated values means nothing to Cucumber.
Your step definition would still look like this:
Then /^I should not get ([^"]*)$/ do |excluded|
# excluded will be a string, "2,3,11"
values = excluded.split(",")
# Do whatever you want with the values
end

testing foreign keys with cucumber

I'm trying to set up the background for a cucumber Feature. Ideally I want to be able to do:
Given the following folders exist:
| id | parent_id | name |
| 1 | nil | folder1 |
| 2 | nil | folder2 |
| 3 | 2 | folder3 |
| 4 | 1 | folder4 |
| 5 | 1 | folder5 |
| 6 | 5 | folder6 |
However I can't do this as I can't set the ID of a particular model and so the first row may be created with an ID of 7 and therefore none of the other "child" rows can access it. Name is not unique so I can't do a find_by_name in the step definition. I've got a feeling it's gonna be some ugly nested array solution.
Any ideas how to achieve this?
I don't understand why you can't choose unique names for the purpose of your configuring the test?
The way I ended up doing it in my step definitions:
Given /^the following folders exist:$/ do |table|
table.hashes.each{|f|
folder = Folder.new(f)
folder.save
ActiveRecord::Base.connection.execute('UPDATE folders SET id = '+f['id'].to_s+' WHERE id = '+folder.id.to_s)
}
end

Resources