在 Specflow 中扩展 StepDefinitions

Extending StepDefinitions in Specflow

我正在尝试使用 Specflow。所以我正在为 REST API 编写功能测试并创建了几个步骤定义,比如 CreatePersonStepDefinitionsGetPeopleStepDefinition

那些扩展 CommonStepDefinition,它提供如下内容:

[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);
}

这是为了能够运行这样的场景

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

所以步骤定义之间有几个共同的步骤。我知道我不能这样做,因为步骤是全球性的。我想问的是什么是最好的方法(即最佳实践)来实现这一点,而不需要在每个步骤定义中重复相同的步骤。

谢谢

因为步骤是全局的,所以您不需要在每个步骤定义中都复制它们,您可以只在所有功能中使用它们,specflow 会调用它们。

如果您真正的问题是如何在我的功能步骤和常用步骤之间共享 ApiKey 和 Response a few ways,但我建议使用 [=25] 中的上下文注入方法=].我会创建上下文对象并将它们传递给您的步骤 类。 Specflow 有一个简单的 DI 框架,它会自动(大部分时间)为您执行此操作。

我会创建这样的东西:

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
}

您甚至可以考虑不使用 Common 步骤,因为这对于所有非特定功能的东西来说都是一个大桶,但我们通常做的是将步骤 类 分解成一些东西像 SecuritySteps 只需要 SecurityContextResponseSteps 只需要 ResponseContext