Can I export descriptive test names in Selenium / Gherkin / Cucumber? - visual-studio

I have a few tests in feature files that use the Scenario Template method to plug in multiple parameters. For example:
#MaskSelection
Scenario Template: The Mask Guide Is Available
Given the patient is using "<browser>"
And A patient registered and logged in
And A patient selected the mask
When the patient clicks on the "<guide>"
Then the patient should see the "<guide>" guide for the mask with "<guideLength>" slides
Examples:
| browser | guide | guideName | guideLength |
| chrome | mask | Mask | 5 |
| firefox | replacement | Mask Replacement Guide | 6 |
| internetexplorer | replacement | Mask Replacement Guide | 6 |
Currently, this is exporting test results with names like "TheMaskGuideIsAvailableVariant3". Is there any way to have it instead export something like "TheMaskGuideIsAvailable("chrome", "mask", "Mask", "5")"? I have a few tests which export 50+ results, and it's a pain to count the list to figure out exactly which set of parameters failed. I could have sworn the export used to work like this at one time, but I can't seem to replicate that behavior.
Possibly tied to it, recently, I've lost the ability to double-click on the test instance in Test Explorer in Visual Studio and go to the test outline in its file. Instead, nothing happens and I have to manually go to that file.

The answer to the Variant situation is that the part that gets appended is the first column of the table. If there are non-unique items in the first column, it gets exported as numbered "Variants".
The answer I found to exporting the list is to use vstest.console with the "/ListTests" option. As per the prior paragraph, since the first column is the one to be used for naming, a column can be established with a concatenated list of parameters.

Related

How to define steps for Scenario Outline with ruby

I have a registration form and need to test it using cucumber and ruby.
I decided to user Scenario Outline with different values in table:
Scenario Outline: Log in with valid data
Given I am on the Sign up Form
When I provide <Email>
And I provide Confirm <СEmail>
And I provide <Password>
And I provide Confirm <СPassword>
And I click on Register button
Then I registered to the site
Examples:
| Email | CEmail | Password | CPassword |
| vip17041#yopmail.com |vip17041#yopmail.com | 123 | 123 |
| vip17042#yopmail.com |vip17042#yopmail.com |123 | 123 |
Now I need create steps definition. In step definition I need to put into the fields values from the table.
How could I do that? Previously I used the next method:
When(/^I provide vip(\d+)#yopmail\.com$/) do |email|
browser.text_field(:name, "Email").set("email#yopmail.com")
But how could I set instead of hard coded email - email from my table?
Thanks
If you're looking to merge the capture with the email address:
When(/^I provide (vip\d+)#yopmail\.com$/) do |email|
browser.text_field(:name, "Email").set("#{email}#yopmail.com")
end
This will concatenate the captured text ("vip" literally plus any number of numerical values with a length of one or more) with the string "#yopmail.com"
A note on how Scenario Outline works
Scenario Outline will grab the lines from the examples table, and simply use the columns to create individual scenarios that use the values that match the column headers in place of the placeholders.
For instance:
Scenario Outline: A note
Given I am logged in as <user>
When I go to the homepage
Then I should see "Welcome Back, <display_name>"
Examples:
| user | display_name |
| rick#stley.com | Rick Astley |
| tammy1992 | Tammy Holmes |
Would be converted into two scenarios:
Scenario: A note
Given I am logged in as rick#stley.com
When I go to the homepage
Then I should see "Welcome Back, Rick Astley"
Scenario: A note
Given I am logged in as tammy1992
When I go to the homepage
Then I should see "Welcome Back, Tammy Holmes"
Which makes it no different to writing your normal scenario, the place holders that you use simply complete the step that you are writing.
How I would write your Scenario
Cucumber is a tool meant to bridge the conversational gap between testers, developers and management.
Scenario Outline: Log in with valid data
Given I am on the Sign up Form
When I sign up with the email "<Email>" and password "<Password>"
Then I should be able to log in as "<Email>" with password "<Password>"
Examples:
| Email | Password |
| vip17041#yopmail.com | 123 |
| vip17042#yopmail.com | 123 |
We don't necessarily have to know each individual step of the process, and the feature file shows the intent of the test.
What this seems to be looking for is whether you can log in after registering a new account, so why not write it as such?
As someone who has used Cucumber for many years I would advise you to avoid using Scenario Outlines. Features and scenarios are for expressing intent in simple clear terms, not programming things using tables.
You can write your scenario as
Scenario: I should be welcomed when I sign in
Given I am registered
When I sign in
Then I should be welcomed
Good scenarios state what behaviour they are trying to verify in their title, and then have steps that are consistent with this behaviour. They have no need to explain HOW your application implements that behaviour. Putting that information in your scenarios makes them longer, harder to implement, and much more difficult to maintain.
A side effect of such simple scenarios is that the step definitions are much simpler and easier to write. No regex's params or table parsing needed here.
You can see a simple example of this approach here (https://github.com/diabolo/cuke_up/tree/master/features),

Using variable with Background in Cucumber

I'm trying to run a feature file like this:
Feature: my feature
Background:
When I do something
And I choose from a <list>
Scenario Outline: choice A
And I click on <something> after the choice A is clicked
Examples:
| list | something |
| a | 1 |
| b | 2 |
| c | 3 |
But what happens is when the second Background step runs, in the step definition, list is a String with the value <list>, and the first Scenario line something is 1, so can Background not use the variables from Examples? Putting a copy of Examples before Scenario Outline does not work.
The answer to your question is: no. Background is not a scenario outline. It does not take values from Examples, which is exclusively for the Scenario Outline where it is included.
Let's suposse you have several Scenario Outlines. Each of them should have its own Examples sections and it is not shared between them. Consequently, it is not shared with Background either.
That is why it does not work when you move Examples before Scenario Outline, as you mentioned in your question.

Visual Studio: Query TFS Work Items: AND/OR Logic doesn't work?

I need to find TFS work items related to a certain topic in our project.
For that purpose, I tried querying the work items using the query builder in Visual Studio.
Since there are multiple terms I wish to search for, I imagined a query like this:
WHERE (
Priority > 300 AND
(Title.Contains('Dog') OR Title.Contains('Cat') OR Title.Contains('Hamster')))
Now, according to http://msdn.microsoft.com/en-us/library/dd286638.aspx (Section And/Or) one should be able to do that like so:
| Priority| > | 300
And | Title | Contains | Dog
Or | Title | Contains | Cat
Or | Title | Contains | Hamster
But... that does not work as described: as far as I can see, this is treated like
(Priority > 300 AND Title.Contains('Dog')) OR Title.Contains('Cat') OR Title.Contains('Hamster')))
Now that is a bit of a problem for me, because apart from a 'Priority' criterion I also have 8 additional criteria that need to apply to all the matches (Date, State, etc.). And I have not only three possible title matches, but around ten. So that multiplies and I would end up with a query that is terribly long and mostly redundant.
.. or, am I missing something here? Is there another way to express those statements? Or is there even another way to query TFS work items, like another tool?
Thanks!
You need to "Group" your Title clauses together to get the query you expect. Select the three "Title" clauses, Right Click and select "Group Clauses".
Here's a snip of a query I created in VS2012 to do this, but it's the same in 2010.
It will only find work items with a Priority >4 and a Title containing either Crash, Error or Working.

Cucumber load data tables dynamically

I am currently trying to use cucumber together with capybara for some integration tests of a web-app.
There is one test where I just want to click through all (or most of) the pages of the web app and see if no error is returned. I want to be able to see afterwards which pages are not working.
I think that Scenario outlines would be the best approach so I started in that way:
Scenario Outline: Checking all pages pages
When I go on the page <page>
Then the page has no HTTP error response
Examples:
| page |
| "/resource1" |
| "/resource2" |
...
I currently have 82 pages and that works fine.
However I find this approach is not maintable as there may new resources and resources that will be deleted.
A better approach would be to load the data from the table from somewhere (parsing HTML of an index page, the database etc...).
But I did not figure out how to do that.
I came across an article about table transformation but I could not figure out how to use this transformation in an scenario outline.
Are there any suggestions?
OK since there is some confusion. If you have a look at the example above. All I want to do is change it so that the table is almost empty:
Scenario Outline: Checking all pages pages
When I go on the page <page>
Then the page has no HTTP error response
Examples:
| page |
| "will be generated" |
Then I want to add a transformation that looks something like this:
Transform /^table:page$/ do
all_my_pages.each do |page|
table.hashes << {:page => page}
end
table.hashes
end
I specified the transformation in the same file, but it is not executed, so I was assuming that the transformations don't work with Scenario outlines.
Cucumber is really the wrong tool for that task, you should describe functionality in terms of features. If you want to describe behavior programmatically you should use something like rspec or test-unit.
Also your scenario steps should be descriptive and specialized like a written text and not abstract phrases like used in a programming language. They should not include "incidental details" like the exact url of a ressource or it's id.
Please read http://blog.carbonfive.com/2011/11/07/modern-cucumber-and-rails-no-more-training-wheels/ and watch http://skillsmatter.com/podcast/home/refuctoring-your-cukes
Concerning your question about "inserting into tables", yes it is possible if you
mean adding additional rows to it, infact you could do anything you like with it.
The result of the Transform block completely replaces the original table.
Transform /^table:Name,Posts$/ do
# transform the table into a list of hashes
results = table.hashes.map do |row|
user = User.create! :name => row["Name"]
posts = (1..row["Posts"]).map { |i| Post.create! :title => "Nr #{i}" }
{ :user => user, :posts => posts }
end
# append another hash to the results (e.g. a User "Tim" with 2 Posts)
tim = User.create! :name => "Tim"
tims_posts = [Post.create! :title => "First", Post.create! :title => "Second"]
results << { :user => tim, :posts => tims_posts }
results
end
Given /^I have Posts of the following Users:$/ do |transformation_results|
transformation_results.each do |row|
# assing Posts to the corresponding User
row[:user].posts = row[:posts]
end
end
You could combine this with Scenario Outlines like this:
Scenario Outline: Paginate the post list of an user at 10
Given I have Posts of the following Users:
| Name | Posts |
| Max | 7 |
| Tom | 11 |
When I visit the post list of <name>
Then I should see <count> posts
Examples:
| name | count |
| Max | 7 |
| Tom | 10 |
| Tim | 2 |
This should demonstarte why "adding" rows to a table, might not be best practice.
Please note that it is impossible to expand example tags inside of a table:
Scenario Outline: Paginate the post list of an user at 10
Given I have Posts of the following Users:
| Name | Posts |
| <name> | <existing> | # won't work
When I visit the post list of <name>
Then I should see <displayed> posts
Examples:
| name | existing | displayed |
| Max | 7 | 7 |
| Tom | 11 | 10 |
| Tim | 2 | 2 |
For the specific case of loading data dynamically, here's a suggestion:
A class, let's say PageSets, with methods, e.g. all_pages_in_the_sitemap_errorcount, developing_countries_errorcount.
a step that reads something like
Given I am on the "Check Stuff" page
Then there are 0 errors in the "developing countries" pages
or
Then there are 0 errors in "all pages in the sitemap"
The Then step converts the string "developing countries" into a method name developing_countries_errorcountand attempts to call it on class PageSets. The step expects all _errorcount methods to return an integer in this case. Returning data structures like maps gives you many possibilities for writing succinct dynamic steps.
For more static data we have found YAML very useful for making our tests self-documenting and self-validating, and for helping us remove hard-to-maintain literals like "5382739" that we've all forgotten the meaning of three weeks later.
The YAML format is easy to read and can be commented if necessary (it usually isn't.)
Rather than write:
Given I am logged in as "jackrobinson#gmail.com"
And I select the "History" tab
Then I can see 5 or more "rows of history"
We can write instead:
Given I am logged in as "a user with at least 5 items of history"
When I select the "History" tab
Then I can see 5 or more "rows of history"
In file logins.yaml....
a member with at least 5 items of history:
username: jackrobinson#gmail.com
password: WalRus
We use YAML to hold sets of data relating to all sorts of entities like members, providers, policies, ... the list is growing all the time:
In file test_data.yaml...
a member who has direct debit set up:
username: jackrobinson#gmail.com
password: WalRus
policyId: 5382739
first name: Jack
last name: Robinson
partner's first name: Sally
partner's last name: Fredericks
It's also worth looking at YAML's multi-line text facilities if you need to verify text. Although that's not usual for automation tests, it can sometimes be useful.
I think that the better approach would be using different tool, just for crawling your site and checking if no error is returned. Assuming you're using Rails
The tool you might consider is: Tarantula.
https://github.com/relevance/tarantula
I hope that helps :)
A quick hack is to change the Examples collector code, and using eval of ruby to run your customized ruby function to overwrite the default collected examples data, here is the code:
generate-dynamic-examples-for-cucumber
drawback: need change the scenario_outline.rb file.

Combinatorial testing with Cucumber

I have a scenario outline that has two different variables. One variable has about 20 different values and the other has 3.
I need to be able to test every single combination and I need each in a separate scenario since they must be tested independently.
Currently, I just write it out by hand(they are integers in the example but not in my test):
Scenario Outline: Test my stuff
Given first var is <var_a>
And second var is <var_b>
When I do stuff
Then good stuff should happen
Examples:
| var_a | var_b |
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
etc...
Question: Is there a way to run this where every combination doesn't have to be written out? The variables are bound to change in size and content later on and I would prefer to have a single data structure to deal with.
Scenario: Test my stuff
Given first var combinations is #var_a_combos
Given second var combinations is #var_b_combos
When I run every combination
Then good stuff should happen
#var_a_combos and #var_b_combos
are an Enumerable that contains every
different possibility for that type.
The When I run every combination
will iterate over both variables and
test every single combination.
Instead of using an assertion, it
will instead create a
#results(String) variable that will
list any failures and their required
debugging data.
The Then good stuff should happen
will run the code #results.should
eql "" to determine whether the test
case passed/failed.
The purpose of using a String variable to hold the results(instead of an assertion) is to ensure that testing does not stop when the first failure is encountered.
I really don't like this solution but it is the best I could come up with so far. I appreciate the other answers but this testing really is integration testing and I really do need to test every combination.
If anyone posts further answers I will review them and change the accepted answer if I think it is better.
Since the tests are for a UI widget, and you're trying to test it at the unit level, you should check out QUnit (or another javascript unit testing framework, but this one's my personal preference). You can even run QUnit tests via cucumber, as in Test sorting with Cucumber and Capybara
Are you sure you really need to test every combination? Could you explain some context around the problem?
Anyway, regarding your query about running everything in a separate scenario, a Scenario Outline with examples is what you need. See the Cucumber docs.

Resources