在场景之间共享数据 Specflow

问题描述 投票:0回答:3

我目前在一个功能文件中有大约 15 个场景,并且希望在它们之间共享数据。我认为上下文注入可以工作,并且它可以在单个场景中的步骤之间工作,但我无法让它将数据从一个场景传递到另一个场景。其他人如何实现这一目标?

specflow
3个回答
1
投票

简短回答:

没有人这样做,因为这是一个坏主意™

长答案:

如果您有对整个功能有效的数据,请将其放入功能上下文中。但这些数据无法在一种场景中修改并在另一种场景中访问。

测试将按照测试运行者确定的顺序执行。不同的跑者可能会选择不同的顺序。执行顺序可能会从运行程序的一个版本更改为下一个版本。测试之间的时间耦合或隐式依赖也会导致其他问题,例如如果我想单独运行测试会发生什么?现在它将失败,因为之前的测试尚未首先运行。如果我想并行运行测试怎么办?现在我不能,因为测试具有需要首先运行的依赖项。

那我能做什么?

我的建议是使用后台步骤(或给定中的明确步骤)来设置您的个人场景所需的数据。 Specflow 使重用这些步骤或让这些步骤重用其他步骤变得相当简单。因此,如果您需要客户和产品来创建订单,并且您有这样的场景:

Scenario: Creating a customer
Given a create a new customer called 'bob'
When I query for customers called 'bob'
Then I should get back a customer

Scenario: Creating a product
Given a create a new product called 'foo'
And 'foo' has a price of £100
When I query for products called 'foo'
Then I should get back a product
And the price should be £100

Scenario: customer places an order
Given I have a customer called 'bob'
And I have a product called 'foo' with a price £100
When 'bob' places an order for a 'foo'
Then an order for 1 'foo' should be created

最后一个场景创建了它需要的所有数据。它可以重复使用与

Given
相同的步骤(具有不同的
Given a create a new customer called 'bob'
属性),并且可以有一个新步骤
And I have a product called 'foo' with a price £100
,它只调用两个现有步骤
Given a create a new product called 'foo'
    And 'foo' has a price of £100

这确保了测试是隔离的并且没有任何依赖性。


1
投票

您可以在另一个类中创建一个变量

static IDictionary<String, Object> globalData
,比如
Global.cs

现在,在场景 1 中:保存任何对象

Globle.globalData.Set("Key", Object);

在场景 2 中:通过对象的键检索对象并将其转换为之前的类型

var dataFromScen1 = Global.globalData.Get("Key");

通过这种方式,您可以将场景 1 中的数据使用到场景 2 中,但是在并行执行期间您将遇到问题


0
投票

您可以使用FeatureContext和ScenarioContext在功能的场景和场景的步骤之间共享数据:

功能上下文从该功能中的第一个场景开始,一直到最后一个场景,同样,场景上下文从该场景中的第一步开始,一直到最后一步

    private readonly FeatureContext _featureContext;
    private readonly ScenarioContext _scenarioContext;
    private readonly IIranMyCreditApiService _iranMyCreditApiService;

    public IranMyCreditApiStepDefinitions(
        FeatureContext featureContext, 
        ScenarioContext scenarioContext,
        IIranMyCreditApiService iranMyCreditApiService)
    {
        _featureContext = featureContext;
        _scenarioContext = scenarioContext;
        _iranMyCreditApiService = iranMyCreditApiService;
    }

    [Given(@"User credentials are as follow")]
    public void GivenUserCredentialsAreAsFollow(Table table)
    { 
        var credentials = table.CreateInstance<UserCredentials>();
        
        _featureContext.Add("credentials", credentials);
    }

    [When(@"requests access token")]
    public void WhenRequestsAccessToken()
    {
        var credentials = _featureContext.Get<UserCredentials>("credentials");
        
        var accessToken = _iranMyCreditApiService.GetAccessTokenAsync(new IranMyCreditApiGetAccessTokenRequestDto
        {
            Username = credentials.Username,
            Password = credentials.Password
        });
        
        _scenarioContext.Add("access-token", accessToken);
    }

    [Then(@"receives a credentials")]
    public void ThenReceivesACredentials(Table table)
    {
        // ScenarioContext.StepIsPending();
    }

    [When(@"refresh the Token")]
    public void WhenRefreshTheToken()
    {
        var accessToken = _scenarioContext.Get<IranMyCreditApiGetAccessTokenResponseDto>("access-token");
        // ScenarioContext.StepIsPending();
    }
© www.soinside.com 2019 - 2024. All rights reserved.