Reputation: 2272
In SpecFlow, I want to check for the presence of a string in a step definition and at the moment I am doing clunky things like this contrived example:
[Given(@"Foo ( bar)?")]
public void GivenFoo(string bar)
{
if (bar == " bar")
{
// do bar
}
}
However, I'd like to do something like this:
[Given(@"Foo ( bar)?")]
public void GivenFoo(bool bar)
{
if (bar)
{
// do bar
}
}
But I can't find out how, so is this possible and if so how?
Upvotes: 9
Views: 11617
Reputation: 5405
You definitely can do that sort of thing, using a StepArgumentTransformation
method. You still have to write the parser logic, but you can sequester it into a method who's only purpose is to perform that parsing.
Example feature file:
Feature: I win if I am Batman
Scenario: Happy
Given I am the Batman
Then I defeat the Joker
Scenario: Sad
Given I am not the Batman
Then I am defeated by the Joker
Specflow Bindings (C#):
[Binding]
public class IWinIfIAmBatmanFeature
{
private bool iAmBatman;
[StepArgumentTransformation(@"(am ?.*)")]
public bool AmToBool(string value)
{
return value == "am";
}
[Given(@"I (.*) the Batman")]
public void WhoAmI(bool amIBatman)
{
iAmBatman = amIBatman;
}
[StepArgumentTransformation(@"(defeat|am defeated by)")]
public bool WinLoseToBool(string value)
{
return value == "defeat";
}
[Then(@"I (.*) the Joker")]
public void SuccessCondition(bool value)
{
Assert.AreEqual(iAmBatman, value);
}
}
The key factor is that the regex match in your Given
clause is matched by the step argument transformation. So in I (.*) the Batman
, if the capture matches the regex in the argument for the StepArgumentTransformation, as it does in the attribute for AmToBool
then that is the transformation that gets used.
Upvotes: 7
Reputation: 388
Based on your question and the comments to Jakub's answer, it looks like you are trying to write a single Step that can cover multiple user journeys through your site. SpecFlow isn't really designed for this, and it's probably an indication that you should try and improve the structure of your scenarios/features.
To answer your question directly, I don't believe there is a way to deduce boolean values based on the existence of certain strings in your step definition.
If you want to persist down this route, then your original example is probably your best bet.
I would recommend that you don't take this approach, however, and instead look at restructuring your step definitions so that you can chain them together, and re-use them across scenarios. I'm actually struggling to think of an example step definition that would fit your solution.
An example of a multi-step approach might look like this:
Given I have logged in as an existing user //1
And I have started my 6-step registration process //2
And I have filled in valid address values on step 1 //3
And I have left the fields blank on step 2 //4
... etc
When I save my registration
And your steps would be:
You just need to ensure that each step is as independent of the others as possible, so you could replace one step with a subtly different one (for a new scenario) without affecting the others.
With this approach you can still end up with complex (and potentially quite verbose) scenarios, but I think that's a better solution than trying to be clever and pack as much into a single step definition. You'll probably end up with scenarios that are unreadable, and the code will probably be a pain to read/maintain as well.
Upvotes: 1
Reputation: 46008
Are you looking for:
[Given(@"I do something (times) times")]
public void GivenIDoSomething(int times)
{
}
Otherwise this seems to suffice
[Given(@"I do something twice")]
public void GivenIDoSomethingTwice()
{
}
EDIT
I think that instead of if
statement in the step you actually want to separate steps.
Upvotes: 0