В Specflow я могу запустить один тест как шаг другого?
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
Извините, немного юмора там.
например, у меня есть тест, который уже создает продажу:
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
И я хочу провести еще один тест, который проверяет добавление строки продаж
И еще один тест, который тестирует завершение продажи
И еще один тест, который отменяет продажу
И так далее
Все эти тесты начинаются с тех же первых четырех шагов, что и простой тест, который нарушает принцип СУХОЙ. Так как я могу сделать так, чтобы первый шаг 2-го теста просто запустил первый тест? например что-то вроде:
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
4 ответа
Как уже отмечалось, вы можете использовать фон для этого (и это, вероятно, лучший вариант в большинстве ситуаций), но вы также можете создать шаг, который вызывает другие шаги.
[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
Преимущество этого заключается в том, что этот составной шаг можно использовать в любом месте сценария, а не только в качестве отправной точки. Этот шаг может быть повторно использован для нескольких функций, если вам нужно
Используйте фон:
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.
Вам не нужно выполнять реальные шаги для создания заказа на продажу. Просто реализуйте определение шага, которое делает это для вас как для одной строки.
Во-первых, вымышленный SalesOrder
учебный класс:
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 и вызовите функцию, созданную на шаге 1.