Specflow — как передать данные, специфичные для среды, из примера таблицы Specflow

У меня есть пара файлов функций Specflow, которые содержат несколько сценариев, и я хочу выполнить их в нескольких средах (DEV, TEST и SIT).

Итак, мой вопрос заключается в следующем: как лучше всего передать данные, специфичные для среды, из файла функций в определение шага. Как видно из приведенного ниже примера, записи о сотрудниках различаются в каждой среде.

Scenario Outline: Employee Search
Given Application is logged
And Search for employee record with <EmployeeName>, <EmployeeID>, <Company>, <Designation> and <Environment>
 Examples: 
        | EmployeeName| EmployeeID| Company  | Designation | Environment |
        | John Smith 1| 123       | ABC      | Analyst     | DEV         |
        | John Smith 2| 456       | DFG      | Manager     | TEST        |
        | John Smith 3| 789       | XYZ      | Sr Analyst  | SIT         |

[When(@"Search for employee record with (.*), (.*), (.*), (.*) and (.*)")]
    public void WhenSearchEmployee (string EmployeeName, string EmployeeID, string Company, string Designation, string Environment)
    {
        if (Environment== "DEV")
        {
            EmployeeRecord.SearchEmployee(EmployeeName, EmployeeID, Company, Designation);
        }
        else if (Environment== "TEST")
        {
            EmployeeRecord.SearchEmployee(EmployeeName, EmployeeID, Company, Designation);
        }
        else if (Environment== "SIT")
        {
            EmployeeRecord.SearchEmployee(EmployeeName, EmployeeID, Company, Designation);
        }
    }

Правки

  • Я идентифицирую среду с файлом app.config

По сути, я хочу выполнить один и тот же тестовый пример в нескольких средах (по одному) с разными данными. Также, если у меня есть две строки в таблице examples, как выполнить только один раз в зависимости от среды.

Это правильный подход? Спасибо.


person Simpal Kumar    schedule 01.08.2019    source источник
comment
Это будет работать. Однако, чтобы сделать шаги повторяемыми в любой среде, можете ли вы создать тестовый пример в сквозном формате и сначала создать запись о сотруднике, а затем выполнить поиск в том же тестовом примере? Таким образом, окружающая среда не имеет значения.   -  person Dazed    schedule 01.08.2019
comment
Кроме того, если вы используете этот формат, как вы настраиваете среду, в которой работаете? Установить его в appconfig и использовать диспетчер конфигурации или настроить локально для каждого запуска с помощью setx?   -  person Dazed    schedule 01.08.2019
comment
Конечно, это не тот подход, который я бы рекомендовал, так как логика в методе не отличается между средами - зачем нам эта условная проверка в методе. Вместо этого вы можете сделать это как scenario и передать детали как datatable, затем получить среду из appconfig и отсортировать необходимые данные из таблицы данных с соответствующей средой. Дайте мне знать, если у вас есть какие-либо вопросы по этому подходу.   -  person supputuri    schedule 01.08.2019
comment
@Dazed - 1. Вышеприведенный код - всего лишь пример, но реальные тестовые примеры, которые у меня есть, намного сложнее, чем этот. Я не могу создать несколько типов записей из пользовательского интерфейса, но мне нужно выполнить поиск по ним. 2. Я использую appconfig и менеджер конфигурации.   -  person Simpal Kumar    schedule 01.08.2019
comment
@supputuri — логика метода для передачи разных данных в зависимости от среды. Если вы видите таблицу примеров выше, у меня разные данные для DEV, TEST и SIT.   -  person Simpal Kumar    schedule 01.08.2019
comment
@supputuri - можете поделиться примером/ссылкой с datatable? По сути, я хочу выполнить один и тот же тестовый пример в нескольких средах с разными данными.   -  person Simpal Kumar    schedule 01.08.2019


Ответы (2)


Если вы не можете каждый раз создавать по запросу, вот еще один способ.

Создайте файл data.cs.

public class EnvData
{
    public EnvData()
    {
        { 
            defaultEmail = "[email protected]";
            defaultPassword = "MyPass123";
        }


        if(ConfigurationManager.AppSettings["Env"] == "Test")
        {
            empName = "John Smith";
            EmployeeID = "1234";
            Company = "McDonalds";
            Designation = "McManager";
           
        }
        else if (ConfigurationManager.AppSettings["Env"] == "Dev")
        {
            empName = "Joe Smith";
            EmployeeID = "3456";
            Company = "McDonalds";
            Designation = "FryGuy";
           
        }
    }

      public static string defaultEmail;
      public static string defaultPassword;
      public static string empName;
      public static string EmployeeID;  //can be an int
      public static string Company;
      public static string Designation;

  }
}

Затем в вашем пошаговом файле мы используем внедрение контекста — https://specflow.org/documentation/context-injection/

    private readonly EnvData _envData;

    public MyClassName(EnvData envData)
    {
        _envData = envData;
    }

Причина, по которой вы делаете это таким образом, заключается в том, что если вам нужно изменить данные, вы изменяете их в одной области, а не в каждом тестовом примере.

Scenario: Employee Search
Given Application is logged
And Search for an employee


  [When(@"Search for employee]
  public void WhenSearchEmployee ()
  {

  //would look something like this...

          EmployeeRecord.SearchEmployee(envData.empName, envData.EmployeeID, envData.Company, envData.Designation);
   
       }

Таким образом, в приведенном выше шаге будет затронут envData и на основе значения appconfig для среды будет получена любая установленная вами информация о сотруднике. Это прекрасно работает, если ваши данные статичны. Я по-прежнему предпочитаю сначала создавать критерии поиска, а затем искать, чтобы вам не приходилось делать все это, лол.

person Dazed    schedule 01.08.2019
comment
Выглядит здорово, но что, если мне придется запускать один и тот же тестовый пример несколько раз, например, у нас есть несколько строк в таблице examples с данными, тогда он будет выполняться для первой строки, затем для второй строки, затем для третьей строки... и так далее... Создание запись поиска будет невозможна, но спасибо за предложение, лол... - person Simpal Kumar; 02.08.2019
comment
Зачем вам использовать пример таблицы? Примеры таблиц используются при передаче данных на шаг. Таблицы-примеры также следует использовать редко, если вообще использовать. В этом сценарии вы передаете данные из файла data.cs, ​​в котором указаны данные для каждой среды и функции. Ваша функция будет предоставлена ​​при поиске по имени, EmpId, назначению и компании. Этот шаг вызовет envData.Name на основе среды, установленной в app.config, и будет использовать эти установленные данные. - person Dazed; 02.08.2019

Поскольку вы уже передаете среду на этом этапе, я бы лично передал это значение конструктору объекта базы данных, который переключает строку подключения из вашего app.config на основе входных данных конструктора.

Пример использования Entity Framework:

public void WhenSearchEmployee (string EmployeeName, string EmployeeID, string Company, string Designation, string Environment) {    
    using (var context = new SomeContext(Environment)) {        
         // Search Employee code here
    }
}

Затем вы можете передать это значение базовому классу DbContext, который может выбрать вашу среду, сопоставив параметр имени из вашего app.config <connectionStrings>. EF сделает это автоматически, но если вы используете ado.net, вы все равно можете сделать что-то подобное.

public partial class SomeContext : DbContext {
    public SomeContext(string dbName) : base($"name={dbName}") {
    }
}

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

person Patrick McDonough    schedule 01.08.2019