I am implementing Behat with Mink, using the following feature:
Scenario: Search for another phrase that exists
Given I am on "/wiki/Main_Page"
When I fill in "search" with "Behavior Driven Development"
And I press "searchButton"
Then I should see "agile software development"
I have used the Goutte and Sahi, and the error is consistent. I get the error on "Then I should see "agile software development"
Scenario: Search for another phrase that exists # features/wikipedia.feature:13
Given I am on "/wiki/Main_Page" # WikipediaFeatureContext::visit()
When I fill in "search" with "Behavior Driven Development" # WikipediaFeatureContext::fillField()
And I press "searchButton" # WikipediaFeatureContext::pressButton()
Then I should see "agile software development"
Ambiguous match of "I should see "agile software development"":
to `/^I should see "([^"]*)"$/` from AccountFeatureContext::iShouldSee()
to `/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/` from WikipediaFeatureContext::assertPageContainsText()
How to fix this issue.
Removed "I" from Then I should see "agile software development" step.
Your gherkin statement is matching more than one method's regex.
You likely have another method in your FeatureContext file which will match "I should see" causing the ambiguous error.
I found that when I came across this I had mistakenly spelled should with a capital S resulting in a new method being appended.
"I Should see "blah blah""
instead of
"I should see "blah blah""
Please check your feature files for any misspelled "I should see..." statements and check your feature context file and remove the extra method.
You'll then be able to write your statements in gherkin syntax properly including your I's
You are including 2 different contexts that define/implement the "same" Step Definition. The I should see "something" step definition comes for free in MinkContext, so my recommendation is removing it from your custom contexts: AccountFeatureContext and WikipediaFeatureContext and including MinkContext:
http://behat.org/en/latest/user_guide/context.html#multiple-contexts
If you put extra logic in your method definition, I recommend creating a new Sentence explaining what exactly you are pretending to see and there use subcontexts for reusing existing implementations:
http://docs.behat.org/en/v2.5/guides/4.context.html
Apart from this consider using another driver different to Sahi, it's no longer maintained:
https://packagist.org/packages/behat/mink-sahi-driver
This issue could also be avoided by making the regular expressions less ambiguous.
The approach you used above still lets you write ambiguous steps.
Best.
Related
Say I have a feature line like this:
And I fill in "Category" with "soccer"
Even though this particular feature line is associated with a search form, I will need to use the same kind of step when dealing with forms in other features.
Where do you guys place this kind of "shared" steps, or in other words, steps that will be used in different features/scenarios?
I have created a file called shared_steps.rb with this content:
And /^I fill in "([^"]*)" with "([^"]*)"$/ do |field,value|
fill_in field, :with => value
end
I don't see anything wrong with placing this type of step in a 'shared_steps.rb' file, that seems perfectly fine.
I would, however, recommend trying to use steps with more explanatory language, such as 'And I search for "soccer" equipment'. There are well documented reasons that the built-in web_steps.rb file is no longer included with Cucumber.
One thing I've often noticed with cucumber is the syntax highlighting for steps such as:
Given /^I have a category with name "([^"]*)"$/ do |category|
...
end
Vim fails to escape the " inside the regex call, and consequently everything after the third " is highlighted as if part of a string. This make it difficult to pick up typos/incorrect methods and half my steps file ends up a (rather unhelpful) shade of red.
So...anyone know of any plugins which can correctly interpret those sorts of steps, and/or an elegant way to rewrite them that doesn't throw off syntax highlighting?
Cheers...
I think this issue is solved with current versions of vim-cucumber and related packages. I do not see what you are saying, using the latest versions of
vim-cucumber
vim-rails
Vim
This is an example of one of our acceptance tests:
Feature: Add an effect to a level
In order to create a configuration
As a user
I want to be able to add effects to a level
Scenario: Add a new valve effect to a level
Given I have created a level named LEVEL123 with description fooDescription
And I am on the configuration page
When I click LEVEL123 in the level tree
And I expand the panel named Editor Panel
And I click the Add Valve Effect button
And the popup named ASRAddVal appears
And I click the Add new button
And I fill in these vertical fields
| field name | value |
| Name | Effect123 |
Then I should see the following texts on the screen
| text |
| Effect added : EFFECT123 |
We feel that this is getting a bit to verbose and we want to hear how you reduce steps in Specflow. From what I've read so far, creating specific non-reusable steps is not recommended, so what is considered "best practice" when doing this in SpecFlow?
Update:
What I am trying to say is that I've learned that you should try to create generic steps in order to re-use them across multiple tests. One way to do that is to parametrize your steps, for example: "Given I have created a level named ..", but the parameterization also introduces verbosity. I want to end up with something like Bryan Oakley suggests in his answer, but I just can't see how I can do that without creating steps which are very specific to each tests. This again means that I'll end up with a lot of steps which reduces maintainability. I looks like SpecFlow has some way of defining abbreviating steps by creating a file which inherits a base class called "Steps", but this still introduces new steps.
So to summarize things; show me a good approach for ending up with Bryan Oakleys answer which is maintainable.
I would simplify it to something like this:
Scenario: Add a new valve effect to a level
Given I have created a new level
When I add a new valve effect with the following values
| field name | value |
| Name | Effect123 |
Then I should get an on-screen confirmation that says "Effect added: Effect123"
The way I approached the problem was to imagine that you are completely redesigning the user interface. Would the test still be usable? For example, the test should work even if there is no "Add" button in the redesign, or you no longer user a popup window.
You could try wording them generically and use parameters.
Given i have create a new: Level
the ':' is only so you can identify the parameter. This means you would have one generic entry point for a step that needs to create a new something. Its up to the step then to look at the parameter of Level and create a new Level
Also try to come up with a naming conversion everyone can use. It should be easy to discover what steps have already been created so you don't get duplicate similar steps.
Can I suggest that maybe the code you are testing should go into unit tests. Maybe what you mean by "test specific" are individual unit tests that are not covered by your acceptance tests.
Just a thought :)
I would like to modify cucumber so that when a given feature is being executed (say "login.feature") I want only login_steps.rb to be loaded for the web steps. Other step files should not be loaded.
IMO this would be very useful to have the same steps but which differ in implementation work accordingly from the feature's name which is being executed.
Since I have almost a hundred scenarios and I would prefer if the steps were of high level steps this would make sense.
Any ideas?
Currently, the only way to accomplish this (short of patching cucumber itself) is to put each feature into a separate directory tree with its own env.rb file and step_definitions directory.
See this post on the mailing list for more details.
You may be able to achieve something like this using the Cellophane gem. It supports nested step definitions and you can turn off looking for shared steps. I'm not sure this will get you all the way to where you want to be, but I've found the developer to be very responsive if cellophane could be modified to get you what you're looking for.
Here is sample code for you,
.feature file
Scenario: Some description of the scenario
Given [some context]
When [some event]
Then [outcome]
.rb (Step Definition in ruby)
Given /^[some context]$/ do
// code module
// code module
end
This step definition will execute whenever [some context] comes in feature file.
says,
Given [some context]
When [some context]
Then [some context]
And [some context]
will perform in same operation. i.e Given, When, Then and And are generic.
Also, you can read behat document for better understanding - http://behat.readthedocs.org/
I just caught myself doing something I do a lot, and wanted to generalize it, express it, share it and see who else is following this general practice, to find some other example situations where it might be relevant.
The general practice is getting something wrong first, on purpose, to establish that everything else is right before undertaking the current task.
What I was trying to do, specifically, was to find examples in our code base where the dojo TextArea widget was used. I knew (because I had it in front of me - existence proof) that the TextBox widget was present in at least one file. So I looked first for what I knew was there:
grep -r digit.form.TextBox | grep -v
svn
This wasn't right - I had made a common (for me) mistake of leaving off the star, so I fixed that:
grep -r digit.form.TextBox * | grep
-v svn
which found no results! Quick comparison with the file I was looking at showed me I had misspelled "dijit":
grep -r dijit.form.TextBox * | grep
-v svn
And now I got results. Cool; doing it wrong first on purpose meant my query was correct except for looking for the wrong thing, so now I could construct the right query:
grep -r dijit.form.TextArea * | grep
-v svn
and be confident that when it gave me no results, it was because there are no such files, and not because I had malformed the query.
I'll add three other examples as answers; please add any others you're aware of.
TDD
The red-green-refactor cycle of test-driven development may be the archetype of this practice. With red, demonstrate that the functionality doesn't exist; then make it exist and demonstrate that you've done so by witnessing the green bar.
http://support.microsoft.com/kb/275085
This VBA routine turns off the "subdatasheets" property for every table in your MS Access database. The user is instructed to make sure error-handling is set to "Break only on unhandled errors." The routine identifies tables needing the fix by the error that is thrown. I'm not sure this precisely fits your question, but it's always interesting to me that the error is being used in a non-error way.
Here's an example from VBA:
I also use camel case when I Dim my variables. ThisIsAnExampleOfCamelCase. As soon as I exit the VBA code line if Access doesn't change the lower case variable to camel case then I know I've got a typo. [OR, Option Explicit isn't set, which is the post topic.]
I also use this trick, several times an hour at least.
arrange - assert - act - assert
I sometimes like, in my tests, to add a counter-assertion before the action to show that the action is actually responsible for producing the desired outcome demonstrated by the concluding assertion.
When in doubt of my spelling, and of my editor's spell-checking
We use many editors. Many of them highlight misspelled words as I type them - some do not. I rely on automatic spell checking, but I can't always remember whether the editor of the moment has that feature. So I'll enter, say, "circuitx" and hit space. If it highlights, I'll back up over the space and the "x" and type another space - and learn that I spelled circuit correctly - but if it doesn't, I'll copy the word and paste it into a known spell-checker to see whether I did.
I'm not sure it's the best way to act, as it does not prevent you from mispelling the final command, for example typing "TestArea" or something like that instead of "TextArea" (your finger just have to slip a little for such a mistake).
IMHO the best way is to run your "final" command, but on two sample files first : one containing the requested text, another that doesn't.
In other words, instead of running a "similar" command, run the real one, but over "similar" data.
(Not sure if this would be a good idea to try for real!)
For example, you might give the system to the users for testing and tell them the password to get started is "Apple".
You know the users are fully up and ready to test (everything is installed and connections to databases working) when they contact you and say the password doesn't work (it's actually "Orange").