在 Specflow 中扩展 StepDefinitions
Extending StepDefinitions in Specflow
我正在尝试使用 Specflow。所以我正在为 REST API 编写功能测试并创建了几个步骤定义,比如 CreatePersonStepDefinitions
和 GetPeopleStepDefinition
那些扩展 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
只需要 SecurityContext
和 ResponseSteps
只需要 ResponseContext
我正在尝试使用 Specflow。所以我正在为 REST API 编写功能测试并创建了几个步骤定义,比如 CreatePersonStepDefinitions
和 GetPeopleStepDefinition
那些扩展 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
只需要 SecurityContext
和 ResponseSteps
只需要 ResponseContext