Problem
I am using SpecFlow to create an integration test suite for a REST service.
I am running the suite in multiple different configurations. (I have multiple Build configurations, each with its own set of app.config transformations.)
In the C# code, it's very simple to check the configuration and execute different code based on it. I can simply do something like this.
[Given(@"I set the test parameter to ""(.*)""")]
public void GivenISetTheTestParameter(string parameter)
{
if(CurrentConfiguration == Config.Test)
this.testParameter = parameter + "Test";
else if(CurrentConfiguration == Config.Prod)
this.testParameter = parameter + "Prod";
}
The problem with this approach is that it works the same way for every execution of this step, but I wan't to parameterize the configuration-dependent part of the step differently in every scenario.
Is there any way to do this in the feature file? I would like to do something like this (pseudo-code, this is not working of course):
If (CurrentConfiguration == Config.Test)
Given I set the test parameter to "ParameterTest"
Else If (CurrentConfiguration == Config.Prod)
Given I set the test parameter to "ParameterProd"
Then I can use this parameterization in a different way in every scenario:
Scenario: Test 1
If (CurrentConfiguration == Config.Test)
Given I set the test parameter to "ParameterTest1"
Else If (CurrentConfiguration == Config.Prod)
Given I set the test parameter to "ParameterProd1"
...
Scenario: Test 2
If (CurrentConfiguration == Config.Test)
Given I set the test parameter to "ParameterTest2"
Else If (CurrentConfiguration == Config.Prod)
Given I set the test parameter to "ParameterProd2"
...
If the condition was implemented in the C# code for the step, this wouldn't be possible.
Real world example
I would like to use this for integration testing a REST service. Let's say I use basic authentication, for which I need to set a header on my RestClient
object.
I have a helper step for setting the auth header to a specific user name and password.
The tricky part is that I have multiple build configurations (let's say Staging and Prod), for which I need different test credentials. Also, I'm calling different APIs in the different scenarios of my feature, which also need different credentials.
So with the above introduced pseudo-syntax, this is what I'd like to do:
Scenario: Test LoggingService
If (CurrentConfiguration == Config.Test)
Given I set the auth header for the user "logging_test_user" and password "p4ssword"
Else If (CurrentConfiguration == Config.Prod)
Given I set the auth header for the user "logging_prod_user" and password "p4ssword"
...
When I call the LoggingService
...
Scenario: Test PaymentService
If (CurrentConfiguration == Config.Test)
Given I set the auth header for the user "payment_test_user" and password "p4ssword"
Else If (CurrentConfiguration == Config.Prod)
Given I set the auth header for the user "payment_prod_user" and password "p4ssword"
...
When I call the PaymentService
...
If I can only put the condition into the C# implementation of the "Given I set the auth header..." step, then I wouldn't be able to specify different user names for the different scenarios.
You don't want the configurable data in your feature files at all. Instead, create a generic step whose definition reads the config file:
And in C#:
And in App.config:
If different usernames have different permissions in the system, then consider using a Scenario Outline instead:
And they become normal parameters to your step definition: