Cucumber (P3) - Parameters và Scenario Outline
Bài đăng này đã không được cập nhật trong 3 năm
Ở phần 1 bạn viết các thành phần trong Cucumber như Features, Screnario, Step Definitions và phần 2 bạn đã cài đặt xong môi trường, bây giờ chúng ta sẽ bắt đầu viết script đầu tiên.
Demo Script
- Mở Project → chuột phải package nằm trong thư mục src/test/java → tạo file feature mới, vd: steps.feature
- Tạo 2 kịch bản để demo trên trang facebook như sau:
Feature: annotation
#This is how background can be used to eliminate duplicate steps
Scenario: Login failed
Given User navigates to Facebook
When I enter username as firstUser
And I enter password as password
And I click Login button
Then Login should fail
Scenario: reLogin
Given User navigates to Facebook
When I enter username as secondUser
And I enter password as password
And I click Login button
Then Relogin option should be available
Then Login should fail
Save file và Run as Cucumber Feature, bạn sẽ thấy ở màn hình console thông báo 8 steps underfined, hiển nhiên là vậy vì Cucumber sẽ tìm code cài đặt step (còn gọi là step definition) để đối chiếu với hành vi mà bạn đã nghĩa trong file feature, mà ở đây bạn chưa cài đặt. Phần dưới bạn quan sát sẽ thấy vài đoạn code gợi ý về việc cài đặt steps, bạn sẽ cài đặt đoạn code này trong phần step definition.
@Given("^User navigates to Facebook$")
@When("^I enter username as firstUser$")
@When("^I enter password as password$")
@Then("^Relogin option should be available$")
@Then("^Login should fail$")
Bạn chú ý rằng các chú thích (annotation) đóng vai trò không quá quan trọng trong Cucumer, ở ví dụ trên bạn có thể thay Given -> When, When -> And thì script của bạn vẫn chạy ngon lành, cái thực sự quan trọng là chuỗi chỉ dẫn bên trong annoation trong file feature và file step definition phải khớp nhau.
- Tạo file StepDefinition.java trong cùng package với file feature, sau đó bạn copy đoạn code gợi ý ở màn hình console vào class vừa tạo.
Để có thể thao tác trên trình duyệt, mình sẽ dùng API của selenium frameword, ở đây, mình khai báo một đối trượng là WebDriver và khởi tạo nó đồng thời import thư viện
org.openqa.selenium.WebDriver;
Dùng XPath Locator để định vị trường username và password, sau đó truyền giá trị thông qua đối số (parameters) userName và pass:
@When("^I enter username as firstUser$")
public void i_enter_username_as_firstUser() throws Throwable {
driver.findElement(By.id("email")).sendKeys("firstUser");
}
@When("^I enter password as password$")
public void i_enter_password_as_password() throws Throwable {
driver.findElement(By.id("pass")).sendKeys("password");
}
Sau khi cài đặt xong step definitions, bạn chọn file feature và Run as Cucumber feature, ở đây mình có 2 scenarios, Cucumber sẽ thực hiện 2 scenarios này một cách độc lập và cho kết quả như sau:
Tuy nhiên kiểm tra kết quả dựa trên màn hình Console không phải là một ý tưởng hay, chúng ta sẽ chạy nó bằng JUnit hoặc TestNG bằng cách: thêm file runTest.java vào cùng package với file feature và stepDefinition, sau đó import thư viện cucumber.junit.Cucumber
và chạy lại file Run as JUnit
import org.junit.runner.RunWith;
import cucumber.junit.Cucumber;
@RunWith(Cucumber.class)
@Cucumber.Options(format = {"pretty", "html:target/cucumber"})
public class runTest {
Bạn có thể thấy kết quả sau khi chạy test rất rõ ràng và dễ hiểu.
bạn có thể tham khảo TestNG, JUnit tại bài viết trước của mình.
Parameters & Scenario Outline
Giả sử bộ data test của bạn bây giờ không chỉ gồm firstUser/password, secondUser/password mà nUser/password, bạn cần chạy hết bộ dữ liệu để đạt được độ bao phủ cao nhất cho feature login này, theo cách thông thường cứ ứng với mỗi bộ user thì bạn cần tạo cho nó một scenario tương ứng, như vậy bạn cần tới n scenario!, như vậy có vẻ không phải là một cách tốt, vì đoạn code và câu lệnh sẽ bị lặp lại rất nhiều, mà điều này cấm kị trong lập trình. Cucumber hỗ trợ sử dụng Parameters và Scenario Outline để bạn giải quyết các vấn đề như trên.
Mình sẽ giữ nguyên phần không đổi của các scenario, còn những data thay đổi thì đặt trong dấu ngoặc kép " ", mình sẽ demo trong 1 scenario như thế này nhé:
Feature: Login fail
Scenario: Login failed
Given User go to Facebook
When I enter username as "nUser"
And I enter password as "password"
And I click Login button
Then Login should fail
Sau khi compile, bạn sẽ thấy dòng code gợi ý lại xuất hiện:
@When("^I enter username as \"([^\"]*)\"$")
@When("^I enter password as \"([^\"]*)\"$")
Ở đây, "nUser" và "password" mà bạn đã định nghĩa trong file feature trên được hiểu là chuỗi xâu, khi chuyển đổi sang step definition, Cucumer dùng Regex pattern để mô tả nó, Regex sẽ được nói ở các phần sau. Tiếp theo, bạn sửa và cài đặt chi tiết đoạn code trên trong file StepDefinition.java như dưới đây, chú ý là thay vì đưa giá trị hardcode (vd: firstUser, password) thì chúng ta truyền tham số (vd: String userName) và sử dụng giá trị này như một biến trong hàm.
@When("^I enter username as \"([^\"]*)\"$")
public void i_enter_username_as(String userName) throws Throwable {
driver.findElement(By.id("email")).sendKeys(userName);
}
@When("^I enter password as \"([^\"]*)\"$")
public void i_enter_password_as(String password) throws Throwable {
driver.findElement(By.id("pass")).sendKeys(password);
}
Bạn save và chạy lại file thành công, như vậy là ta đã thêm parameters cho scenario test demo. Tiếp theo, làm sao để chạy cùng một scenario với nhiều bộ data test khác nhau trong khi các steps vẫn giữ nguyên thì khi đó bạn dùng tới Scenario Outline. Bạn thay đổi tên khai báo Scenario → Scenario Outline, thêm bộ ngoặc <> vào parameters và cung cấp bộ data test sau từ khóa Examples
Feature: Login fail
Scenario Outline: Login failed
Given User navigates to Facebook
When I enter username as "<nUser>"
And I enter password as "<password>"
And I click Login button
Then Login should fail
Examples: Page titles
| nUser | password |
| firstUser | password1 |
| secondUser | password2 |
| thirdUser | password3 |
| fourthUser | password4 |
Với mỗi bộ data test: nUser - password, Cucumber sẽ thực thi nó như là một scenario độc lập, kết quả của scenario sau không phụ thuộc vào kết quả của scenario trước. Đầu tiên Cucumber sẽ tìm các paramters ("<nUser>") và chèn data được cung cấp trong Examples (firstUser) để tạo ra một scenario hoàn chỉnh, sau đó nó tìm step definition tương ứng và chạy test thành công. Chọn file runTest.java và Run as JUnit, ta có kết quả sau:
Bạn có thể tùy chỉnh tham số và giá trị trong Examples cho phù hợp với mục đích test trong dự án, ở phần tiếp theo chúng ta sẽ tìm hiểu Tag và Datatables. Enjoy it!
Source code https://github.com/TrangVuUet/demoCucumber
All rights reserved