Сценарий Cucumber утверждает условие в DataTable

#java #cucumber #cucumber-jvm

#java #cucumber #cucumber-jvm

Вопрос:

У меня есть следующий сценарий в Cucumber-jvm, и мне интересно, как лучше всего это написать.

 Given I create a process
When I execute the following tasks with parameters:
|Task Name| param1 | param2| param3|
...
Then each task should have outcomes:
|Task Name| outcome1 | outcome2| outcome3|
  

Каков наилучший способ приблизиться к этому?

Мне нужно выполнить When Task1, затем Task1, за которым следует When Task2, Затем Task2 и т. Д. Из-за потери информации о состоянии при запуске следующей задачи. Вместо того, чтобы сначала вызывать все задачи When1,2,3, за которыми сначала следуют задачи Then1,2,3.

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

Я мог бы объединить When / Then в один шаг, но это кажется неправильным.

Есть предложения?

Ответ №1:

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

Чтобы избежать Given step повторения, вы можете настроить статическую логическую переменную в вашем определении шага java и проверить ее как флаг.

 Scenario Outline:
Given I create a process
When I execute the following task <TaskName> with parameters:
|<Parameter1>|<Parameter2>|<Parameter3>|
Then each task <TaskName> should have outcomes:
|<Outcome1>|<Outcome2>|<Outcome3>|

Examples:
|TaskName|Parameter1|Parameter2|Parameter3|Outcome1|Outcome2|Outcome3|
|task1|t1param1|t1param2|t1param3|t1out1|t1out2|t1out3|
|task2|t2param1|t2param2|t2param3|t2out1|t2out2|t2out3|
.......
  

Если у вас переменное количество параметров и результатов, измените их, используя строку, разделенную символами. Вы можете использовать @Transform annotation в определении шага, чтобы получить объект параметров или результатов.

 Scenario Outline:

Given I create a process
When I execute the following task <TaskName> with parameters <parameters>
Then each task <TaskName> should have outcomes <outcomes>

Examples:
| TaskName | Parameters | Outcomes |
| task1 | t1param1,t1param2,t1param3| t1out1,t1out2,t1out3 |
| task2 | t2param1,t2param2,t2param3| t2out1,t2out2,t2out3 |
.......
  

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


Последний сценарий — Это большой взлом, зависящий от того, что идентификатор сценария остается неизменным. Добавьте количество сценариев в таблицу примеров для последнего шага, как показано ниже.

 Scenario Outline:

    Given I create a process
    When I execute the following task <TaskName> with parameters <parameters>
    Then each task <TaskName> should have outcomes <outcomes>
    ***And Last step to run for last scenario 3***

    Examples:
    | TaskName | Parameters | Outcomes |
    | task1 | t1param1,t1param2,t1param3| t1out1,t1out2,t1out3 |
    | task2 | t2param1,t2param2,t2param3| t2out1,t2out2,t2out3 |
    | task3 | t3param1,t3param2,t3param3| t3out1,t3out2,t3out3 |


Include in StepDefinition.java

private Scenario scenario;

@Before
public void before(Scenario sce) {
    this.scenario = sce;
    System.out.println("SCENARIO ID -- "  scenario.getId());
}
  

Вы получите строку, подобную для схемы сценария — **feature-description ; scenariooutline-description ; example-description ; rownumber 1** . Например — validating-sample;so1;se1;2 . Это будет для первой строки таблицы примеров.

Для случая схемы сценария вы можете разделить с помощью разделителя «;» и использовать последнюю часть после вычитания 1. Поместите эту логику в метод getCurrentExamplesRow()

 @Then("^Last step to run for last scenario (\d )$")
public void lastStep(int size) {

    // Will be called only for last scenario in examples... 
    if(size==getCurrentExamplesRow()) {

    }
}
  

Комментарии:

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

2. Я проверю это и отвечу в ближайшее время

3. Есть ли способ вырваться из схемы сценария? Т.Е. выполнить один оператор then после итерации примеров?

4. Каждая строка в таблице примеров выполняется как автономный сценарий сам по себе. Вы хотите выполнить шаг Then только для последнего сценария в таблице примеров или для любого сценария в зависимости от некоторой логики?

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

Ответ №2:

Ваша проблема вызвана выполнением этого шага

 When I execute the following tasks with parameters:
|Task Name| param1 | param2| param3|
...
  

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

 When I xxx
  

Затем ваша задача — найти замены (имена) для xxx. Эти имена должны описывать, каков совокупный эффект выполнения всех ваших задач.

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

Теперь список задач, которые вы должны выполнить, вы только что назвали task (КАК), может быть определен далее по вашему стеку. Это может быть в ваших определениях шагов, вспомогательных методах для определений шагов или, что еще лучше, в вашем реальном коде.

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

 fill the kettle with 350ml of cold water
switch of the kettle just before its boiled
pour 5ml of water into each cup to warm them
switch on the kettle until its boiled
... 
...
zzzzzz
  

То, что вы делаете в своем сценарии, так же глупо, как говорить кому-то все это вместо make some tea !

Весь смысл Cucumber с использованием естественного языка заключается в том, чтобы позволить авторам сценариев использовать возможности естественного языка для написания простых и выразительных вещей. Каждый раз, когда вы позволяете деталям ТОГО, КАК что-то делается, проскальзывать в сценарий, вы не можете эффективно использовать язык.

Комментарии:

1. Спасибо за объяснение абстракции для меня!

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

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

4. Когда людям требуется время, чтобы ответить на ваши вопросы, вы могли бы, по крайней мере, с помощью civil, даже если вы не согласны с ответом. Сарказм не является подходящим ответом. Никогда не встречаясь с вами, я понятия не имею о вашем уровне понимания абстракции. Все, что мне нужно продолжить, это ваш пост, и это указывает на то, что вы не применяете абстракцию к этой конкретной проблеме. Мой 10-летний опыт использования Cucumber показывает, что решение вашей проблемы заключается в применении абстракции к вашим сценариям. Меня это устраивает, если вам не нравится мой ответ, но нет необходимости быть грубым.