Extending StepDefinitions in Specflow

天大地大妈咪最大 提交于 2019-12-24 16:20:38

问题


I trying to experiment with Specflow. So I am writing functional tests for a REST API and have created a couple of step definitions, say CreatePersonStepDefinitions and GetPeopleStepDefinition

Those extend CommonStepDefinition, which provides things like:

[Given(@"a valid API key is given")]
public void AValidApiKeyIsGiven()
{
     ApiKey = "Some Api Key";
}

[Then(@"the response HTTP code should be (.*)")]
public void ThenTheStatusCodeShouldBe(int statusCode)
{
     Assert.AreEqual (statusCode, (int)Response.StatusCode);
}

This is to be able to run scenarios like

Given I am retrieving all people
And an invalid API key is given
When I make the call
Then the response HTTP code should be 200
And the API response code is 104
And the API call didn't take more than 200 milliseconds

So there are several common steps between step definitions. I understand that I cannot do this as Steps are global. What I wanted to ask is whats the best way (i.e. best practise) to achieve this without duplicating the same steps in every step definition.

Thanks


回答1:


Because steps are global you don't need to duplicate them in every step definition, you can just use them in ALL features, and specflow will call them.

If your real question is how do I share the ApiKey and Response between my features steps and my common steps there are a few ways but what I would recommend is to use the context injection approqach from the link. I would create context objects and pass these to your step classes. Specflow has a simple DI framework which will do this automatically (most of the time) for you.

I would create something like this:

public class SecurityContext
{
    public string ApiKey {get;set;}
}

public class ResponseContext
{
    public IHttpResponse Response{get;set;}
}

[Binding]
public class CommonSteps
{
     private SecurityContext securityContext;
     private ResponseContext responseContext;
     public CommonSteps(SecurityContext securityContext,ResponseContext responseContext)
    {
         this.securityContext = securityContext;
         this.responseContext = responseContext;
    }

    [Given(@"a valid API key is given")]
    public void AValidApiKeyIsGiven()
    {
         securityContext.ApiKey = "Some Api Key";
    }

    [Then(@"the response HTTP code should be (.*)")]
    public void ThenTheStatusCodeShouldBe(int statusCode)
    {
         Assert.AreEqual (statusCode, (int)responseContext.Response.StatusCode);
    }
}

public class MyFeatureSteps
{
     private SecurityContext securityContext;
     private ResponseContext responseContext;

     public MyFeatureSteps(SecurityContext securityContext,ResponseContext responseContext)
    {
         this.securityContext = securityContext;
         this.responseContext = responseContext;
    }

    ///Then in your feature steps you can use the Api key you set and set the response
}

you might even consider not having Common steps as this get just be a big bucket for everything that is not feature specific, but what we usually do is to break the step classes into something like SecuritySteps which would just take the SecurityContext and ResponseSteps which would just take the ResponseContext



来源:https://stackoverflow.com/questions/32671707/extending-stepdefinitions-in-specflow

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!