1. Введение
Хуки Cucumber могут пригодиться, когда мы хотим выполнить определенные действия для каждого сценария или шага, но без явного указания этих действий в коде Gherkin.
В этом уроке мы рассмотрим хуки @Before
, @BeforeStep, @AfterStep
и @After
Cucumber.
2. Обзор хуков в Cucumber
2.1. Когда следует использовать хуки?
Хуки можно использовать для выполнения фоновых задач, не являющихся частью бизнес-функций. Такими задачами могут быть:
- Запуск браузера
- Установка или очистка файлов cookie
- Подключение к базе данных
- Проверка состояния системы
- Мониторинг
Примером использования для мониторинга может быть обновление информационной панели с ходом тестирования в режиме реального времени.
Хуки не видны в коде Gherkin. Поэтому мы не должны рассматривать их как замену Огуречного фона или заданного шага .
Мы рассмотрим пример, в котором мы используем хуки для создания снимков экрана во время выполнения теста.
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()
Итак, когда мы выполняем сценарий, сначала выполняется initialization()
, а потом — beforeScenario()
.
3.2. @BeforeStep
Методы, аннотированные @BeforeStep,
выполняются перед каждым шагом . Давайте воспользуемся аннотацией, чтобы делать скриншот перед каждым шагом:
@BeforeStep
public void beforeStep() {
takeScreenshot();
}
3.3. @AfterStep
Методы, аннотированные @AfterStep,
выполняются после каждого шага :
@AfterStep
public void afterStep() {
takeScreenshot();
}
Здесь мы использовали @AfterStep
, чтобы делать снимки экрана после каждого шага. Это происходит независимо от того, завершается шаг успешно или нет .
3.4. @После
Методы, аннотированные @After,
выполняются после каждого сценария :
@After
public void afterScenario() {
takeScreenshot();
closeBrowser();
}
В нашем примере мы сделаем последний снимок экрана и закроем браузер. Это происходит независимо от того, завершается ли сценарий успешно .
3.5. Параметр сценария
_
Методы, аннотированные аннотацией ловушки, могут принимать параметр типа Scenario
:
@After
public void beforeScenario(Scenario scenario) {
// some code
}
Объект типа Сценарий
содержит информацию о текущем сценарии. Включены имя сценария, количество шагов, имена шагов и статус (пройдено или не пройдено). Это может быть полезно, если мы хотим выполнять разные действия для пройденных и не пройденных тестов.
4. Выполнение крючка
4.1. Счастливый поток
Давайте теперь посмотрим, что происходит, когда мы запускаем сценарий Cucumber со всеми четырьмя типами хуков:
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, мы можем увидеть порядок выполнения:
Во- первых, выполняются два наших хука @Before
. Затем до и после каждого шага запускаются хуки @BeforeStep
и @AfterStep
соответственно. Наконец, запускается хук @After .
Все хуки выполняются для обоих сценариев.
4.2. Несчастный поток: неудавшийся шаг
Давайте посмотрим, что произойдет, если шаг не удастся. Как видно на снимке экрана ниже, выполняются хуки @Before
и @After
неудачного шага. Последующие шаги пропускаются, и, наконец, выполняется хук @After
:
Поведение @After
похоже на предложение finally
после try-catch
в Java. Мы могли бы использовать его для выполнения задач очистки, если шаг не удался. В нашем примере мы по-прежнему делаем снимок экрана, даже если сценарий не работает.
4.3. Несчастный поток: хук не работает
Давайте посмотрим, что происходит, когда выходит из строя сам хук. В приведенном ниже примере первый @BeforeStep
терпит неудачу.
В этом случае фактический шаг не запускается, но запускается хук @AfterStep .
Последующие шаги также не будут выполняться, тогда как хук @After
выполняется в конце:
5. Условное выполнение с тегами
Хуки определяются глобально и влияют на все сценарии и шаги. Однако с помощью тегов Cucumber мы можем точно определить, для каких сценариев должен выполняться хук:
@Before(order=2, value="@Screenshots")
public void beforeScenario() {
takeScreenshot();
}
Этот хук будет выполняться только для сценариев, помеченных тегом @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. Ява 8
Мы можем добавить поддержку Cucumber Java 8 , чтобы определить все хуки с лямбда-выражениями.
Вспомним наш хук инициализации из примера выше:
@Before(order=2)
public void initialization() {
startBrowser();
}
Переписав лямбда-выражение, мы получим:
public BookStoreWithHooksRunSteps() {
Before(2, () -> startBrowser());
}
То же самое работает и для @BeforeStep
, @After
и @AfterStep
.
7. Заключение
В этой статье мы рассмотрели, как определить хуки Cucumber.
Мы обсудили, в каких случаях мы должны их использовать, а когда нет. Затем мы увидели, в каком порядке выполняются хуки и как мы можем добиться условного выполнения.
Наконец, мы увидели, как можно определять хуки с помощью лямбда-нотации Java 8.
Как обычно, полный исходный код этой статьи доступен на GitHub .