Сценарий переноса огурца в схему сценария

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

Scenario: This scenario loops through the lines of the table performing an assert on each line
    When I do something and verify it
      | name         | parameter1 | parameter2   | parameter3 |
      | A and 1      | A          | 1            | true       |
      | B and 1      | B          | 1            | false      |
      | A and 2      | A          | 2            | false      |
      | B and 2      | B          | 2            | true       |

Определение шага выглядит так:

@When("I do something and verify it")
public void doSomethingAndVerifyIt(DataTable dataTable) {
    List<Map<String, String>> keyValues = dataTable.asMaps();
    for (Map<String, String> keyValue : keyValues) {
        assertSomething(keyValue.get("parameter1"), keyValue.get("parameter2"), keyValue.get("parameter3"));
    }
}

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

Scenario Outline: This scenario loops through the lines of the table performing an assert on each line
    When I do something and verify it

Examples:
      | name         | parameter1 | parameter2  | parameter3 |
      | A and 1      | A          | 1           | true       |
      | B and 1      | B          | 1           | false      |
      | A and 2      | A          | 2           | false      |
      | B and 2      | B          | 2           | true       |

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

Есть ли более простой способ сделать это в следующих строках:

@When("I do something and verify it")
public void doSomethingAndVerifyIt(Map<String, String> keyValue) {
    assertSomething(keyValue.get("parameter1"), keyValue.get("parameter2"), keyValue.get("parameter3"));
}

person user304582    schedule 30.03.2020    source источник


Ответы (2)


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

Scenario Outline: eating
  Given there are <start> cucumbers
  When I eat <eat> cucumbers
  Then I should have <left> cucumbers

  Examples:
    | start | eat | left |
    |    12 |   5 |    7 |
    |    20 |   5 |   15 |




person diabolist    schedule 01.04.2020
comment
Да, я знаю, что включение параметров в качестве явных параметров в шаги сработает, но, честно говоря, я надеялся этого избежать. У меня много параметров, и я надеялся просто прочитать их как карту для каждой строки в таблице примеров, а не объявлять их по отдельности. Это кажется вполне естественным желанием сделать! - person user304582; 02.04.2020
comment
Вы не можете этого сделать, Огурец не знает, что с ними делать. Если у вас есть сложные данные, которые вы хотите запрограммировать в сценарии, вам следует воспользоваться моим первым подходом. Размещение большого количества строк данных в сценариях - действительно плохой антишаблон. Я понимаю, что программирование функций кажется естественным занятием, но это абсолютно противоречит их дизайну и функциям. Сделайте работу, чтобы превратить каждую строку данных (каждый пример) в правило. Это не только улучшит ваши сценарии, но и поможет улучшить код, если вы позволите это сделать. - person diabolist; 03.04.2020

См. Мой другой ответ о том, как использовать table.

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

Скажем, у нас есть

password     | success?

123456       |   no
xb32drthcyfe |   no
p@ssword1    |   yes

как наши примеры. Проблема в том, что мы не знаем, ПОЧЕМУ xb32drthcyfe должен потерпеть неудачу, а p@ssword1 - добиться успеха. Мы можем догадываться, но наш сценарий не смог зафиксировать ПОЧЕМУ.

Теперь рассмотрим

Scenario: Passwords must contain a symbol
 When I register with a password without a symbol
 Then I should see my password needs a symbol

Теперь у вас есть единственный сценарий, который не только документирует ПОЧЕМУ, но и позволяет вам оспаривать ПОЧЕМУ и исследовать ПОЧЕМУ, например

Scenario: Weak password that contains a symbol
 Given my password is long enough has a symbol but it is really weak
 When I register with my password
 Then I should be registered.

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

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

person diabolist    schedule 31.03.2020
comment
Спасибо за вашу помощь. Есть большая разница между двумя способами запуска этих тестов. Первое завершится ошибкой, как только одно утверждение не сработает, и поэтому не все строки таблицы могут быть проверены. Во втором случае все четыре теста будут запущены, и их результаты будут сообщены независимо от того, прошел или не прошел в других строках. Информация о правилах интересна, но не имеет отношения к моему вопросу. - person user304582; 31.03.2020
comment
Извините за мою ошибку, вы правы в этом. Я никогда не использую таблицы или схемы сценариев, так что простите меня за эту ошибку. Остальная часть сообщения по-прежнему актуальна. Что касается того, как заставить ваш план сценария работать, см. Мой второй ответ. Я отредактировал первый ответ, чтобы удалить ошибку. - person diabolist; 01.04.2020