Куки за краставици

1. Въведение

Кукичките за краставици могат да бъдат полезни, когато искаме да извършим конкретни действия за всеки сценарий или стъпка, но без тези действия да са изрично в кода на корнишона.

В този урок ще разгледаме куките @Before , @BeforeStep, @AfterStep и @After Cucumber.

2. Преглед на куките в краставицата

2.1. Кога трябва да се използват куки?

Куките могат да се използват за изпълнение на фонови задачи, които не са част от бизнес функционалността. Такива задачи могат да бъдат:

  • Стартиране на браузър
  • Задаване или изчистване на бисквитки
  • Свързване към база данни
  • Проверка на състоянието на системата
  • Мониторинг

Случаят на употреба за наблюдение би бил да се актуализира таблото с напредъка на теста в реално време.

Куките не се виждат в кода на корнишона. Следователно не бива да ги възприемаме като заместител на фона на краставицата или дадена стъпка .

Ще разгледаме пример, при който използваме куки, за да правим екранни снимки по време на изпълнението на теста.

2.2. Обхват на куките

Куките засягат всеки сценарий. Следователно е добра практика да дефинирате всички куки в специален клас за конфигуриране.

Не е необходимо да се дефинират едни и същи куки във всеки клас лепилен код. Ако дефинираме куки в същия клас с нашия лепилен код, ще имаме по-малко четим код.

3. Куки

Нека първо разгледаме отделните куки. След това ще разгледаме пълен пример, където ще видим как се изпълняват куки, когато се комбинират.

3.1. @Преди

Методите, анотирани с @Before, ще се изпълняват преди всеки сценарий . В нашия пример ще стартираме браузъра преди всеки сценарий:

@Before public void initialization() { startBrowser(); }

Ако анотираме няколко метода с @Before , можем изрично да дефинираме реда, в който се изпълняват стъпките:

@Before(order=2) public void beforeScenario() { takeScreenshot(); }

Горният метод изпълнява второ, тъй като предаваме 2 като стойност за параметъра за поръчка към анотацията. Също така можем да предадем 1 като стойност за параметъра за поръчка на нашия метод за инициализация:

@Before(order=1) public void initialization()

Така че, когато изпълняваме сценарий, инициализацията () се изпълнява първо, а beforeScenario () изпълнява второто.

3.2. @BeforeStep

Методите, анотирани с @BeforeStep, се изпълняват преди всяка стъпка . Нека използваме анотацията, за да направим екранна снимка преди всяка стъпка:

@BeforeStep public void beforeStep() { takeScreenshot(); }

3.3. @AfterStep

Методи, отбелязани с @AfterStep, се изпълняват след всяка стъпка :

@AfterStep public void afterStep() { takeScreenshot(); }

Използвахме @AfterStep тук, за да направим екранна снимка след всяка стъпка. Това се случва независимо дали стъпката завършва успешно или не .

3.4. @След

Методи, отбелязани с @ След изпълнение след всеки сценарий :

@After public void afterScenario() { takeScreenshot(); closeBrowser(); }

В нашия пример ще направим последна екранна снимка и ще затворим браузъра. Това се случва независимо дали сценарият завършва успешно .

3.5. В Сценарий параметър

Методите, анотирани с анотация на кука, могат да приемат параметър от тип Сценарий :

@After public void beforeScenario(Scenario scenario) { // some code }

Обектът от тип Scenario съдържа информация за текущия сценарий. Включени са името на сценария, броя на стъпките, имената на стъпките и състоянието (преминаване или неуспех). Това може да бъде полезно, ако искаме да изпълняваме различни действия за преминати и неуспешни тестове.

4. Изпълнение на кука

4.1. Честит поток

Нека сега разгледаме какво се случва, когато стартираме сценарий за краставица с всичките четири вида куки:

Feature: Book Store With Hooks Background: The Book Store Given The following books are available in the store | The Devil in the White City | Erik Larson | | The Lion, the Witch and the Wardrobe | C.S. Lewis | | In the Garden of Beasts | Erik Larson | Scenario: 1 - Find books by author When I ask for a book by the author Erik Larson Then The salesperson says that there are 2 books Scenario: 2 - Find books by author, but isn't there When I ask for a book by the author Marcel Proust Then The salesperson says that there are 0 books

Разглеждайки резултата от тестово изпълнение в IntelliJ IDE, можем да видим реда за изпълнение:

First, our two @Before hooks execute. Then before and after every step, the @BeforeStep and @AfterStep hooks run, respectively. Finally, the @After hook runs. All hooks execute for both scenarios.

4.2. Unhappy Flow: a Step Fails

Let's see what happens if a step fails. As we can see in the screenshot below, both the @Before and @After hooks of the failing step are executed. The subsequent steps are skipped, and finally, the @After hook executes:

The behavior of @After is similar to the finally-clause after a try-catch in Java. We could use it to perform clean-up tasks if a step failed. In our example, we still take a screenshot even if the scenario fails.

4.3. Unhappy Flow: a Hook Fails

Let's look at what happens when a hook itself fails. In the example below, the first @BeforeStep fails.

In this case, the actual step doesn't run, but it's @AfterStep hook does. Subsequent steps won't run either, whereas the @After hook is executed at the end:

5. Conditional Execution with Tags

Hooks are defined globally and affect all scenarios and steps. However, with the help of Cucumber tags, we can define exactly which scenarios a hook should be executed for:

@Before(order=2, value="@Screenshots") public void beforeScenario() { takeScreenshot(); }

This hook will be executed only for scenarios that are tagged with @Screenshots:

@Screenshots Scenario: 1 - Find books by author When I ask for a book by the author Erik Larson Then The salesperson says that there are 2 books

6. Java 8

We can add Cucumber Java 8 Support to define all hooks with lambda expressions.

Recall our initialization hook from the example above:

@Before(order=2) public void initialization() { startBrowser(); }

Rewritten with a lambda expression, we get:

public BookStoreWithHooksRunSteps() { Before(2, () -> startBrowser()); }

The same also works for @BeforeStep, @After, and @AfterStep.

7. Conclusion

In this article, we looked at how to define Cucumber hooks.

We discussed in which cases we should use them and when we should not. Then, we saw in which order hooks execute and how we can achieve conditional execution.

Накрая видяхме как можем да дефинираме куки с ламбда нотация Java 8.

Както обикновено, пълният изходен код на тази статия е достъпен в GitHub.