Подтвердить что ты не робот

Спектр и повторное использование шагов из другой функции

Я пытаюсь изучить specflow и прямо сейчас. В настоящее время у меня есть 2 файла функций.

Во втором файле свойств я повторно использую шаг из первого файла функции.

Спектрометр автоматически распознает шаг из первого файла функции, и когда specflow генерировал шаги для моей второй функции, он был умным и не восстановил тот шаг, который я повторно использовал.

Но этот шаг - это заданный шаг, и он инициализирует поле члена класса объектов.

Без использования контекста сценария, как я могу повторно использовать шаг из другого файла функции, который инициализирует член класса?

Изменить

Например, если у вас есть заданный, я вошел в систему, который используется в нескольких файлах функций. Этот "заданный" создает пользовательский объект, который регистрируется и хранит его как член в файле функций .cs.

Если вы используете тот же параметр в другом .feature, то Specflow не регенерирует его в соответствующем файле .cs. Когда вы отлаживаете сценарий, который его использует, он выполняет его из первого файла .cs.

Но я не могу получить доступ к члену первого файла функций .cs. Я планирую использовать статический член, но, возможно, есть другое решение?

Большое спасибо.

4b9b3361

Ответ 1

Большая точка здесь в том, что Step Binding являются глобальными. Это, кажется, общий анти-шаблон с Specflow, который проходит много людей. Первоначально у вас есть этап создания иерархии привязывающих классов, соответствующих вашим файлам функций. Вместо этого вам нужно создать классы сотрудничества, которые не соответствуют функциям, а вместо этого создают функции благодаря совместной работе.

Это как ваш основной код приложения. У вас не было бы одного класса ATMMachineCashWithdrawal, вместо этого у вас был бы ATMMachine, который имеет PINCodeCheck, OperationSelection и WithdrawalOperation. Эти объекты взаимодействуют, чтобы сделать вашу функцию "Я хочу снять деньги", и когда вы добавляете функцию "Проверить мой баланс", вы можете использовать все, кроме WithdrawalOperation.

Связи в Specflow одинаковы. У нас может быть ATMTester, который знает, как настроить ATMMachine и поставляет ваш Given I have a cash machine full of cash, и у вас может быть CustomerTester, который знает, как подделка/макет/настройка баланса вашего аккаунта с помощью Given my account has loads of money in it.

К счастью, SpecFlow предоставляет способы совместной работы с классами. Посмотрите http://www.specflow.org/documentation/Sharing-Data-between-Bindings/

Ответ 2

У меня была такая же проблема. Вам необходимо установить атрибут "Binding" для производных классов и задать область для каждого из них.

Скажем, у вас есть 2 Особенности:

  • Функция: Моя первая функция
  • Функция: Моя вторая функция

    Feature: My First Feature
    Background: 
    Given a precondition
    When ...
    Then ...
    
    Feature: My Second Feature
    Background: 
    Given a precondition
    When ...
    Then ...
    

и у вас есть BaseClass, определяющий совместное поведение

    // no Binding attribute for the BaseClass
    public class BaseClass
    {
        [Given(@"a precondition")]
        public void GivenAPrecondition()
        {
        }
    }

а затем 2 класса, определяющие поведение для двух функций

[Binding]
[Scope(Feature = "My First Feature")]
public class MyFirstFeature : BaseClass
{

}

[Binding]
[Scope(Feature = "My Second Feature")]
public class MySecondFeature : BaseClass
{

}

Ответ 3

Одна вещь, которую я сделал, используется один, массивный partial class разделенный между различными *.cs файлами.

Это позволяет хранить релевантные вещи в своих собственных файлах, но при этом дает вам много вариантов повторного использования вашего кода устройства.

например. (Feature1Steps.cs)

namespace YourProject.Specs
{
    [Binding] // This can only be used once.
    public partial class YourProjectSpecSteps
    {
        // Feature 1 methods ...
    }
}

И для следующей функции (Feature2Steps.cs)

namespace YourProject.Specs
{
    public partial class YourProjectSpecSteps // same class, already bound
    {
        // Feature 2 methods ...
    }
}