在 Specflow 中,我可以 运行 一个测试作为另一个步骤吗?
In Specflow can I run one test as a step of another?
TL;DR;如何创建调用另一个测试作为第一步的 specflow 测试?
Given I already have one specflow test
And I want to run another test that goes deeper than the first test
Then I create a second test that runs the first test as its first step
And I add additional steps to test the deeper functionality
抱歉,有点 specflow 幽默。
例如,我有一个已经创建销售的测试:
Given I want to create a sales order
And I open the sales order page
And I click the add new order button
Then a new sales order is created
而且我想进行另一个测试来测试添加销售线
还有另一个测试完成销售的测试
还有另一个取消销售的测试
还有..等等
所有这些测试都将从与简单测试相同的前四个步骤开始,这违反了 DRY 原则。 那么我该怎么做才能让第二个测试的第一步只运行第一个测试呢?例如:
Given I have run the create sales order test // right here it just runs the first test
And I add a sales order line
Then the order total is updated
如果每个测试都以相同的前四行开始,后来我意识到我需要更改简单的创建销售测试,那么我还需要去查找并修复重复这四行的所有其他地方行。
编辑:请注意,这也应该能够跨功能工作。例如上面的简单测试是在销售功能中定义的。但我也会有一个积分功能,这需要每次都创建一个销售才能记入它:
Given I want to credit a sale
And I run the create sales order test
And I complete the the sale
And I click the credit button
Then the sale is credited
使用背景:
Background:
Given I want to create a sales order
And I open the sales order page
And I click the add new order button
Then a new sales order is created
Scenario: I add another sale
When I add a sales order line
Then the order total is updated
Scenario: I add cancel a sale
When I cancel a sale
Then the order total is updated to 0
etc.
如前所述,您可以为此使用背景(这可能是大多数情况下的最佳选择),但您也可以创建一个调用其他步骤的步骤。
[Binding]
public class MySteps: Steps //Inheriting this base class is vital or the methods used below won't be available
{
[Given("I have created an order")]
public void CreateOrder()
{
Given("I want to create a sales order");
Given("I open the sales order page");
Given("I click the add new order button");
Then("a new sales order is created");
}
}
然后您可以在您的场景中使用它:
Scenario: I add another sale
Given I have created an order
When I add a sales order line
Then the order total is updated
这样做的好处是这个复合步骤可以在场景中的任何地方使用,而不仅仅是作为起点。如果需要,可以在多个功能中重复使用此步骤
您不需要 运行 实际步骤来创建销售订单。只需实现一个步骤定义,即可为您完成此操作。
先虚构SalesOrder
class:
public class SalesOrder
{
public double Amount { get; set; }
public string Description { get; set; }
}
然后步骤定义
using TechTalk.SpecFlow;
using TechTalk.SpecFlow.Assist;
[Binding]
public class SalesOrderSteps
{
[Given("I have already created a Sales Order")]
public void GivenIHaveAlreadyCreatedASalesOrder()
{
var order = new SalesOrder()
{
// .. set default properties
};
// Save to scenario context so subsequent steps can access it
ScenarioContext.Current.Set<SalesOrder>(order);
using (var db = new DatabaseContext())
{
db.SalesOrders.Add(order);
db.SaveChanges();
}
}
[Given("I have already created a Sales Order with the following attributes:")]
public void GivenIHaveAlreadyCreatedASalesOrderWithTheFollowingAttributes(Table table)
{
var order = table.CreateInstance<SalesOrder>();
// Save to scenario context so subsequent steps can access it
ScenarioContext.Current.Set<SalesOrder>(order);
using (var db = new DatabaseContext())
{
db.SalesOrders.Add(order);
db.SaveChanges();
}
}
}
现在您可以将销售订单创建为单行订单,并可选择包含一些自定义属性:
Scenario: Something
Given I have already created a Sales Order
Scenario: Something else
Given I have already created a Sales Order with the following attributes:
| Field | Value |
| Amount | 25.99 |
| Description | Just a test order |
如果您需要在其他步骤定义中访问该 SalesOrder
对象而不在数据库中查询它,请使用 ScenarioContext.Current.Get<SalesOrder>()
从场景上下文中检索该对象。
如果我理解正确,你想跨不同的特征文件调用其他场景。
- 您可以通过创建一个调用步骤的步骤来处理这个问题
场景(基本上是嵌套的步骤,比如接受的答案
以上)。
- 将创建的步骤添加到后台
或
- 创建一个函数来调用场景中的步骤。
- 需要销售订单为前提的场景添加标签@create_sale_order。
- 为标签@create_sale_order 实现一个 before scenario hook 并调用在步骤 1 中创建的函数。
TL;DR;如何创建调用另一个测试作为第一步的 specflow 测试?
Given I already have one specflow test
And I want to run another test that goes deeper than the first test
Then I create a second test that runs the first test as its first step
And I add additional steps to test the deeper functionality
抱歉,有点 specflow 幽默。
例如,我有一个已经创建销售的测试:
Given I want to create a sales order
And I open the sales order page
And I click the add new order button
Then a new sales order is created
而且我想进行另一个测试来测试添加销售线
还有另一个测试完成销售的测试
还有另一个取消销售的测试
还有..等等
所有这些测试都将从与简单测试相同的前四个步骤开始,这违反了 DRY 原则。 那么我该怎么做才能让第二个测试的第一步只运行第一个测试呢?例如:
Given I have run the create sales order test // right here it just runs the first test
And I add a sales order line
Then the order total is updated
如果每个测试都以相同的前四行开始,后来我意识到我需要更改简单的创建销售测试,那么我还需要去查找并修复重复这四行的所有其他地方行。
编辑:请注意,这也应该能够跨功能工作。例如上面的简单测试是在销售功能中定义的。但我也会有一个积分功能,这需要每次都创建一个销售才能记入它:
Given I want to credit a sale
And I run the create sales order test
And I complete the the sale
And I click the credit button
Then the sale is credited
使用背景:
Background:
Given I want to create a sales order
And I open the sales order page
And I click the add new order button
Then a new sales order is created
Scenario: I add another sale
When I add a sales order line
Then the order total is updated
Scenario: I add cancel a sale
When I cancel a sale
Then the order total is updated to 0
etc.
如前所述,您可以为此使用背景(这可能是大多数情况下的最佳选择),但您也可以创建一个调用其他步骤的步骤。
[Binding]
public class MySteps: Steps //Inheriting this base class is vital or the methods used below won't be available
{
[Given("I have created an order")]
public void CreateOrder()
{
Given("I want to create a sales order");
Given("I open the sales order page");
Given("I click the add new order button");
Then("a new sales order is created");
}
}
然后您可以在您的场景中使用它:
Scenario: I add another sale
Given I have created an order
When I add a sales order line
Then the order total is updated
这样做的好处是这个复合步骤可以在场景中的任何地方使用,而不仅仅是作为起点。如果需要,可以在多个功能中重复使用此步骤
您不需要 运行 实际步骤来创建销售订单。只需实现一个步骤定义,即可为您完成此操作。
先虚构SalesOrder
class:
public class SalesOrder
{
public double Amount { get; set; }
public string Description { get; set; }
}
然后步骤定义
using TechTalk.SpecFlow;
using TechTalk.SpecFlow.Assist;
[Binding]
public class SalesOrderSteps
{
[Given("I have already created a Sales Order")]
public void GivenIHaveAlreadyCreatedASalesOrder()
{
var order = new SalesOrder()
{
// .. set default properties
};
// Save to scenario context so subsequent steps can access it
ScenarioContext.Current.Set<SalesOrder>(order);
using (var db = new DatabaseContext())
{
db.SalesOrders.Add(order);
db.SaveChanges();
}
}
[Given("I have already created a Sales Order with the following attributes:")]
public void GivenIHaveAlreadyCreatedASalesOrderWithTheFollowingAttributes(Table table)
{
var order = table.CreateInstance<SalesOrder>();
// Save to scenario context so subsequent steps can access it
ScenarioContext.Current.Set<SalesOrder>(order);
using (var db = new DatabaseContext())
{
db.SalesOrders.Add(order);
db.SaveChanges();
}
}
}
现在您可以将销售订单创建为单行订单,并可选择包含一些自定义属性:
Scenario: Something
Given I have already created a Sales Order
Scenario: Something else
Given I have already created a Sales Order with the following attributes:
| Field | Value |
| Amount | 25.99 |
| Description | Just a test order |
如果您需要在其他步骤定义中访问该 SalesOrder
对象而不在数据库中查询它,请使用 ScenarioContext.Current.Get<SalesOrder>()
从场景上下文中检索该对象。
如果我理解正确,你想跨不同的特征文件调用其他场景。
- 您可以通过创建一个调用步骤的步骤来处理这个问题 场景(基本上是嵌套的步骤,比如接受的答案 以上)。
- 将创建的步骤添加到后台
或
- 创建一个函数来调用场景中的步骤。
- 需要销售订单为前提的场景添加标签@create_sale_order。
- 为标签@create_sale_order 实现一个 before scenario hook 并调用在步骤 1 中创建的函数。