Nội dung bài học
✅ Cách sử dụng Cucumber Tags
✅ Cucumber Hook là gì?
Cucumber Hooks là các khối mã chạy trước hoặc sau mỗi kịch bản. Bạn có thể xác định chúng ở bất kỳ đâu trong các lớp định nghĩa bước hoặc dự án của mình, bằng cách sử dụng các phương thức @Before và @After. Cucumber Hooks cho phép chúng ta quản lý tốt hơn thứ tự thực thi code và giúp chúng ta giảm bớt sự dư thừa của mã.
Cucumber Hooks nó giống như các Annotation trong TestNG thuần, cho phép chúng ta thực hiện các kịch bản hoặc thử nghiệm của mình theo một thứ tự và cho phép thiết lập các nội dung trong chính các bước thứ tự ấy.
Cụ thể trong Cucumber Hooks hỗ trợ chúng ta các ghi chú sau: @BeforeAll, @AfterAll, @Before, @After, @BeforeStep @AfterStep
✅ Tại sao sử dụng Cucumber Hook?
Như chúng ta cũng thấy trong TestNG thì các ghi chú như @BeforeClass, @BeforeMethod giúp cho chúng rất nhiều trong khâu thiết lập Driver, load data,...và sau khi chạy xong thì @AfterMethod tự đóng driver ấy rất tiện lợi. Thì trong Cucumber nó cũng như thế. Với các ghi chú cụ thể bên trên An có đề cập.
Hooks có thể được sử dụng để thực hiện các tác vụ nền tự động không phải gọi đi gọi lại gì cả và cũng không liên quan đến Gherkin. Những tác vụ chạy có thể là:
- Khởi động trình duyệt
- Đặt hoặc xóa cookie
- Kết nối với cơ sở dữ liệu
- Kiểm tra trạng thái của driver
- Đóng kết nối
- ...
✅ Các ghi chú trong Hooks
🔆 @BeforeAll và @AfterAll
Trong phiên bản Cucumber 7.0.0 về sau thì BeforeAll và AfterAll được triển khai. BeforeAll chạy trước khi bất kỳ kịch bản nào được chạy và AfterAll chạy sau khi tất cả các kịch bản đã được thực thi.
@BeforeAll và @AfterAll tương tự như các chú thích @BeforeSuite và @AfterSuite của TestNG. Bạn có thể sử dụng các móc nối toàn cầu này khi cần thiết lập hoặc dọn dẹp toàn cục cái gì đó. Ví dụ: thiết lập các biến môi trường, cơ sở dữ liệu hoặc cấu hình reports và dọn dẹp các cookies...
Bạn cần sử dụng trạng thái static cho phương thức, không giống như các hook khác.
@BeforeAll
import io.cucumber.java.BeforeAll;
@BeforeAll
public static void beforeAll() {
// Runs before all scenarios
}
@AfterAll
import io.cucumber.java.AfterAll;
@AfterAll
public static void afterAll() {
// Runs after all scenarios
}
🔆 @Before
Các phương thức được chú thích bằng @Before sẽ thực thi trước mọi kịch bản. Trong ví dụ dưới chúng ta có thể khởi động trình duyệt trước mọi tình huống:
@Before
public void beforeScenario() {
startBrowser();
}
🔆 @After
Các phương thức được chú thích bằng @After sẽ thực thi sau mọi kịch bản. Trong ví dụ dưới chúng ta có thể tắt trình duyệt trước mọi tình huống:
@After
public void afterScenario() {
closeBrowser();
}
🔆 @BeforeStep
Các phương thức được chú thích bằng @BeforeStep sẽ thực thi trước mỗi bước (mỗi step). Có thể sử dụng chú thích này để chụp ảnh màn hình trước mỗi bước hoặc ghi logs và bước trong reports:
@BeforeStep
public void beforeStep() {
takeScreenshot();
//logs
//write to report
}
🔆 @AfterStep
Các phương thức được chú thích bằng @AfterStep sẽ thực thi sau mỗi bước. Có thể sử dụng chú thích này để chụp ảnh màn hình sau mỗi bước thất bại hoặc thành công tuỳ mình đặt điều kiện hoặc ghi logs và bước trong reports:
@AfterStep
public void afterStep() {
takeScreenshot();
//logs
//write to report
}
🔆 Thông số Scenario
Các phương thức được chú thích bằng hook annotation có thể chấp nhận một tham số kiểu Scenario:
@After
public void afterScenario(Scenario scenario) {
// some code
}
Đối tượng của Scenario chứa thông tin về kịch bản hiện tại. Bao gồm tên kịch bản, số bước, tên của các bước và trạng thái (đạt hoặc không đạt). Điều này có thể hữu ích nếu chúng ta muốn thực hiện các hành động khác nhau đối với các bài kiểm tra đạt và không đạt. Có thể chụp màn hình hay ghi vào report chẳng hạn.
✅ Thực thi có điều kiện với các ghi chú
Hooks được xác định trên toàn cầu và ảnh hưởng đến tất cả các kịch bản và bước. Tuy nhiên, với sự trợ giúp của các thẻ thuộc tính Cucumber, chúng ta có thể xác định chính xác kịch bản nào của hook sẽ được thực hiện trước sau và gọi đúng điều kiện.
@Before(order=2, value="@Screenshots")
public void beforeScenario() {
takeScreenshot();
}
Ví dụ trên thì nó sẽ chạy thứ 2 nghĩa là sau một @Before khác. Và nó sẽ áp dụng đối với Scenario nào có Tag là @Screenshot
✅ Thiết kế Cucumber Hooks vào code
Chúng ta tạo packacge "hooks" bên package "src/test/java" nghĩa là để bên test. Và chúng ta tạo một class bất kỳ ví dụ CucumberHooks rồi khai báo các Ghi chú bên trên ra.
package com.anhtester.hooks;
import com.anhtester.common.BaseTest;
import com.anhtester.helpers.CaptureHelpers;
import com.anhtester.helpers.PropertiesHelpers;
import io.cucumber.java.*;
public class CucumberHooks {
@BeforeAll
public static void beforeAll() {
System.out.println("================ beforeAll ================");
PropertiesHelpers.loadAllFiles();
//Khởi chạy Report
}
@AfterAll
public static void afterAll() {
System.out.println("================ afterAll ================");
}
@Before
public void beforeScenario() {
System.out.println("================ beforeScenario ================");
BaseTest.createDriver();
//Record video
}
@After
public void afterScenario(Scenario scenario) {
System.out.println("================ afterScenario ================");
BaseTest.closeDriver();
}
@BeforeStep
public void beforeStep(Scenario scenario) {
System.out.println("================ beforeStep ================");
//Ghi file log4j
//Ghi log step vào report
}
@AfterStep
public void afterStep(Scenario scenario) {
System.out.println("================ afterStep ================");
//validate if scenario has failed then Screenshot
if (scenario.isFailed()) {
CaptureHelpers.takeScreenshot(scenario.getName());
}
}
}
Sau đó chúng ta gọi đường dẫn của package chứa CucumberHooks vào mỗi cái Test Runer để nó tự nhận diện được.
@CucumberOptions(
features = "src/test/resources/features/Login/LoginCRM.feature",
glue = {
"com.anhtester.stepdefinitions",
"com.anhtester.common",
"com.anhtester.hooks"
},
plugin = {"pretty", "html:target/cucumber-html-report.html"})
@Test
public class TestRunnerLoginCRM extends AbstractTestNGCucumberTests {
}
Kết quả:
Anh Tester
facebook.com/anhtester
Đường dẫu khó chân vẫn cần bước đi
Đời dẫu khổ tâm vẫn cần nghĩ thấu