Kait Mentimun

1. Perkenalan

Kail mentimun dapat berguna saat kita ingin melakukan tindakan tertentu untuk setiap skenario atau langkah, tetapi tanpa tindakan ini secara eksplisit dalam kode Gherkin.

Dalam tutorial ini, kita akan melihat kait @Before , @BeforeStep, @AfterStep, dan @After Cucumber.

2. Sekilas tentang Kail di Mentimun

2.1. Kapan Hooks Harus Digunakan?

Hooks dapat digunakan untuk melakukan tugas latar belakang yang bukan merupakan bagian dari fungsionalitas bisnis. Tugas semacam itu bisa berupa:

  • Memulai browser
  • Mengatur atau menghapus cookie
  • Menghubungkan ke database
  • Memeriksa status sistem
  • Pemantauan

Kasus penggunaan untuk pemantauan adalah memperbarui dasbor dengan kemajuan pengujian secara real-time.

Hook tidak terlihat di kode Gherkin. Oleh karena itu, kita tidak boleh melihatnya sebagai pengganti Latar Belakang Ketimun atau langkah tertentu .

Kami akan melihat contoh di mana kami menggunakan hook untuk mengambil tangkapan layar selama eksekusi uji.

2.2. Lingkup Pengait

Pengait memengaruhi setiap skenario. Oleh karena itu, praktik yang baik untuk menentukan semua hook dalam kelas konfigurasi khusus.

Tidak perlu menentukan kait yang sama di setiap kelas kode lem. Jika kita mendefinisikan pengait di kelas yang sama dengan kode lem kita, kita akan memiliki kode yang kurang bisa dibaca.

3. Pengait

Pertama mari kita lihat masing-masing kait. Kami kemudian akan melihat contoh lengkap di mana kami akan melihat bagaimana hook dieksekusi saat digabungkan.

3.1. @Sebelum

Metode yang dianotasi dengan @Before akan dijalankan sebelum setiap skenario . Dalam contoh kami, kami akan memulai browser sebelum setiap skenario:

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

Jika kita menganotasi beberapa metode dengan @Before , kita dapat secara eksplisit menentukan urutan eksekusi langkah-langkah:

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

Metode di atas mengeksekusi kedua, saat kita meneruskan 2 sebagai nilai untuk parameter order ke anotasi. Kita juga dapat mengirimkan 1 sebagai nilai untuk parameter urutan metode inisialisasi kita:

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

Jadi, ketika kita mengeksekusi skenario, inisialisasi () mengeksekusi pertama, dan beforeScenario () mengeksekusi kedua.

3.2. @Tokopedia

Metode yang dianotasi dengan @BeforeStep dijalankan sebelum setiap langkah . Mari gunakan anotasi untuk mengambil tangkapan layar sebelum setiap langkah:

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

3.3. @After

Metode yang dianotasi dengan @AfterStep dijalankan setelah setiap langkah :

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

Kami telah menggunakan @AfterStep di sini untuk mengambil tangkapan layar setelah setiap langkah. Ini terjadi terlepas dari apakah langkah tersebut selesai dengan sukses atau gagal .

3.4. @Setelah

Metode yang dianotasi dengan @After dijalankan setelah setiap skenario :

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

Dalam contoh kami, kami akan mengambil tangkapan layar terakhir dan menutup browser. Ini terjadi terlepas dari apakah skenario berhasil diselesaikan .

3.5. The Scenario Parameter

The methods annotated with a hook annotation can accept a parameter of type Scenario:

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

The object of type Scenario contains information on the current scenario. Included are the scenario name, number of steps, names of steps, and status (pass or fail). This can be useful if we want to perform different actions for passed and failed tests.

4. Hook Execution

4.1. Happy Flow

Let's now look at what happens when we run a Cucumber scenario with all four types of hooks:

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

Looking at the result of a test run in the IntelliJ IDE, we can see the execution order:

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.

Akhirnya, kami melihat bagaimana kami dapat mendefinisikan hook dengan notasi lambda Java 8.

Seperti biasa, kode sumber lengkap artikel ini tersedia di GitHub.