SpecFlow uncertainty in bindings
I've been working with Spec-flow for several days now. I came across "Multiple match found. Navigating to first match" while debugging this can be solved, but when I run the whole solution it doesn't work due to ambiguous bindings. I am running 4 files with a clear class in one project
Feature: ConversionUnencrypted Pdf-Pdf
@mytag
Scenario Outline: ConversionUnencrypted Pdf-Pdf
Given I get Inputs Folder and list of Files <inputFolder> then <getInputTokens>(Multiple bindings for this line)
Given I get <outputDirectory>
Given I set saving Mode <ConversionMode>
Given I convert pdf using Conversion
Given I convert to Image <convertToFile>
Then I compare Images <getActualImagePath> and <getExpectedImagePath> and <pageCount>
and step definitions:
**Binding for Multiple steps is the below binding:**
First binding:
[Given(@"I get Inputs Folder and list of Files (.*) then (.*)")]
public void GivenIGetInputsFolderAndListOfFilesThen(string getInputFolder, string getInputTokens)
{
--logic--
}
Second binding:
[Given(@"I get (.*)")]
public void GivenIGet(string getOutputDirectory)
{
--logic--
}
Second binding changed to:
Given I set OutputDirectory of Pdf <outputDirectory>
[Given]
public void Given_I_set_OutputDirectory_of_Pdf_P0(string p0)
{
--logic--
}
This one doesn't help me either. Tried Regex also failed to solve the problem. There is ambiguity in the above 2 bindings. Its not only in one function is also observed in another file with functions. How can this be solved so that each row matches one anchor?
source to share
As @perfectionist pointed out your problem is with your regexes. One consumes all characters for both. Try this instead:
Feature: ConversionUnencrypted Pdf-Pdf
@mytag
Scenario Outline: ConversionUnencrypted Pdf-Pdf
Given I get Inputs Folder and list of Files '<inputFolder>' then '<getInputTokens>'
Given I get '<outputDirectory>'
...
and step definitions:
[Given(@"I get Inputs Folder and list of Files '([^']*)' then '([^']*)'")]
public void GivenIGetInputsFolderAndListOfFilesThen(string getInputFolder, string getInputTokens)
{
}
[Given(@"I get '([^']*)'")]
public void GivenIGet(string getOutputDirectory)
{
--logic--
}
This regex will only match when the input does not contain a character '
, so it will prevent the second method from being too greedy when consuming the input and matching a longer method.
Generally, I prefer to wrap string characters in single quotes as above in the script, as it makes problems like this a little easier to mitigate
Obviously the above will only work if your inputs '<inputFolder>','<getInputTokens>' and <outputFolder>
contain no characters '
. If so, you may need a more complex regex
source to share
I think I can guess a piece of the missing information.
The problem is the binding for these two lines:
Given I get Inputs Folder and list of Files <inputFolder> then <getInputTokens>
Given I get <outputDirectory>
The first commitment you listed:
[Given(@"I get Inputs Folder and list of Files (.*) then (.*)")]
public void GivenIGetInputsFolderAndListOfFilesThen(string getInputFolder, string getInputTokens)
{
// etc
}
I am assuming a second binding.
[Given(@"I get (.*)")]
public void GivenIGet(string outputDirectory)
{
// etc
}
The second binding matches any text that begins with "Considering what I get", including of course any text that begins with "Given that I am getting a folder named Inputs and a list of files ..."
If you want to avoid binding conflicts, you will need to be more specific with the given-I-get binding. That being said, you should choose a language that a business expert (not a code expert) will understand for your steps - โI getโ is probably not what a business expert would say. But it might be, in high tech organizations - in which case you will need to make the Regex more specific to the pathpath / uri file.
Spectrum cannot be used efficiently without understanding Regex. (.*)
is the most permissive capture group, and even if set by default by plugflow, this is rarely a good answer. For a quick list of symbols you can use and to check out regex ideas, why not check out rubular.com .
source to share
You need to use anchored binding so that scenarios and stages with the same descriptions can be separated. See Walkthrough here:
http://www.specflow.org/documentation/Scoped-bindings/
or here:
source to share