13

I am following the technique outlined here

using a step defined like

[Given("some base scenario has happened")]
public void SomeBaseScenarioHasHappened()
{
   Given("some condition");
   And("some action");
   When("some result");
}

from a scenario like

Scenario: Some dependant scenario
Given some condition 
And some base scenario has happened
When some other action
Then some other result

However the step

  When some other condition

produces the following error -> No matching step definition found for the step. Use the following code to create one:

[When(@"some other condition")]
public void Whensome other condition()
{
ScenarioContext.Current.Pending();
}

I can work around the problem by having the base scenario only use Given

[Given("some base scenario has happened")]
public void SomeBaseScenarioHasHappened()
{
   Given("some condition");
   Given"some action");
   Given("some result");
}

however this is not what I should have to do. Am I missing something? Why cant the base scenario be called using an AND ?

Community
  • 1
  • 1
Kirsten
  • 15,730
  • 41
  • 179
  • 318
  • 1
    Need to see your binding for the "some other condition" step. – perfectionist Aug 04 '14 at 07:12
  • its not 100% clear what your issue is. It looks like your composite step (`[Given("some base scenario has happened")]`) works ok as specflow is complaining about your `And some other condition` step being unbound. Have you generated a step binding for this step? ie is there a method with an attribute `[Given("some other condition")]` in your step bindings? – Sam Holder Aug 04 '14 at 09:51
  • it would be useful to see your original step bindings (the "some condition", "some action", "some result" ones) as well as the bindings for your new scenario (the "some base scenario has happened", "some other condition", "some other action", "some other result" ones) – Sam Holder Aug 04 '14 at 09:53
  • I am so sorry that there was a mistake in my question. The problem is to do with the base scenario being called using an AND. I can work around it by making sure that the base scenario is called using a Given – Kirsten Aug 04 '14 at 16:11
  • kirsten, see my answer, that is exactly what I have listed as the problem and why that is. – Sam Holder Aug 04 '14 at 16:12
  • Sam can you update your answer to state that also I cant call the composite step using an AND. I still don't understand why since Specflow should be treating it as a Given. – Kirsten Aug 04 '14 at 16:20
  • 1
    sure. I'll explain the reason why you can't use AND in there as well. (and tag me with @Sam in the comments rather than just Sam then stackoverflow will give me a notification that you have commented to me) – Sam Holder Aug 04 '14 at 16:37

4 Answers4

14

In Specflow there are only 3 types of steps. Given, When and Then. When you use a step with And in your scenario description SpecFlow looks at the previous type of step and assumes that your And step is of the same type.

So when you write this

Scenario: Some dependant scenario
    Given some base scenario has happened
    And some other condition
    When some other action
    Then some other result

Specflow looks for step which have bindings:

    Given("some base scenario has happened")
    Given("some other condition")
    When("some other action")
    Then("some other result")

Notice there is no And binding?

So your solution is to to ensure that in your composite step you must avoid using And and just use the same binding (or one of them if they have multiple) that the original step had. Your final solution should look something like this:

[Given("some condition")]
public void SomeCondition()
{
   ...
}

[When("some action")]
public void SomeAction()
{
   ...
}

[Then("some result")]
public void SomeResult()
{
   ...
}

[Given("some base scenario has happened")]
public void SomeBaseScenarioHasHappened()
{
   Given("some condition");
   When("some action");
   Then("some result");
}

[Given("some other condition")]
public void SomeOtherCondition()
{
   ...
}

[When("some other action")]
public void SomeOtherAction()
{
   ...
}

[Then("some other result")]
public void SomeOtherResult()
{
   ...
}

You can't use And in the composite steps because no steps are actually bound with an And, there is no such binding - The only bindings are Given, When or Then. The And and But keywords are only used when generating the unit tests that are run, the steps using those keywords are still bound to a Given, When or Then step ultimately.

In a scenario definition the things are processed in order and you can easily tell what an And step actually is based on the step it appears after, so when specflow generates the step bindings it knows what step type to use (either a Given, When or Then). When you are calling a a step from within another step you are explicitly calling one of those step bindings and you have to call it with the binding that it is bound with. So if it was bound with a Given binding like this:

[Given("some other condition")]
public void SomeOtherCondition()
{
   ...
}

then you have to call it like this from the code:

Given("Some other condition");

but you could refer to it like this in a scenario:

Given some condition
And some other condition

because specflow knows when it generates the unit test that the And some other condition is actually calling a Given bound step

Sam Holder
  • 32,535
  • 13
  • 101
  • 181
  • @kirsteng I've updated my answer. Hope this clears up why you have to use only `Given`, `When` and `Then` and can't use `And` – Sam Holder Aug 04 '14 at 16:47
  • @sam_holder I understand why I cant use AND in a composite step, but your answer doesn't explain why I also cant use it to call the method that contains the composite steps. i.e I cant use AND some base scenario has happened, I must use GIVEN Some base scenario has happened – Kirsten Aug 04 '14 at 16:56
  • @kirsteng I'm suprised that you can't call the step using `And`. I see you have edited the original question, but now it doesn't make any sense as you say the error is `And some other condition` but that step doesn't exist now in your scenario. Perhaps you could update your question with an accurate representation of the issue (or just post another one?) – Sam Holder Aug 04 '14 at 17:00
  • @sam_holder, you are right, I can no longer produce the problem I thought I was having, so it must boil down to not using AND inside the composite steps – Kirsten Aug 04 '14 at 17:11
  • 1
    @kirsteng all's well that ends well :) – Sam Holder Aug 04 '14 at 17:12
7

This question has been previously answered correctly above.

I just came across the same error "No matching step definition found for one or more steps".

The reason that I had this issue, was that I had forgotten to put the attribute [Binding, Scope(Feature = "My Feature")] just above my steps c# code class which links methods to feature file, which is needed to match "Feature: My Feature" at the top of my feature file.

I just taught that I would document it here to help someone else that was seeing the same error but for the different reason that I outlined.

Mike
  • 827
  • 11
  • 27
  • 1
    Thanks Mike. When I have added scope attribute along with Binding attribute then i am able to fix the issue `[Binding, Scope(Feature = "SpecFlowFeature1")]` – Janardhan Reddy Oct 31 '20 at 14:20
3

Possible solutions

Use Given instead of And

Scenario: Some dependant scenario
Given some base scenario has happened
Given some other condition   
When some other action
Then some other result

or

Tag the step with more than one binding, e.g.

[Given(@"some other condition")]
[When(@"some other condition")]
public void Whensome other condition()
{

but this won't always make semantic sense, so use this only when it really does make sense.

perfectionist
  • 4,256
  • 1
  • 23
  • 34
  • I did this and it helped with my work around, but it doesn't explain why Specflow is looking for a When, when it should be looking for a Given – Kirsten Aug 04 '14 at 07:30
  • 1
    Yes. I'll need to put some time in to reproduce the error to be able to answer accurately. But it feels like (1) it is a bug, and (2) you aren't expected to use "when" and "then" type steps inside a "given", so the bug is under the radar. I'm not sure using when and then inside given is good practice. I might be able to expand on this in my answer in about 12 hours, when I'm home from work. – perfectionist Aug 04 '14 at 08:36
0

try verifying if your sentence has empty spaces. i.e: Given some description(empty space) so, in the method will appear like: [Given("some description ")]