[ThaoVTP][Dịch bài viết] Thực hiện test tự động Browser bằng Selenium WebDriver -Phần 2

Ở phần 1, tôi đã giới thiệu một cách đơn giản về 3 đặc trưng, môi trường và cách code của tool tự động hóa test Web mà Java, C#, Python, Ruby có thể sử dụng cho Browser: Chrome, Firefox, Internet Explorer, Opera, Android, iOS. Phần này tôi sẽ lấy ví dụ về tạo test case, design class, trình tự test, thực hiện coding, etc…

Sử dụng sample quản lý thông tin nhân viên làm ví dụ test Selenium WebDriver

Trong bài trước「Selenium WebDriver-vũ khí cuối cùng của test tự động Browser bao gồm cả iPhone/Adroid」tôi đã giải thích khái quát về Selenium WebDriver và khái quát môi trường tiền đề và cách thức thực hiện để có thể sử chạy sample. Bây giờ tôi sẽ giải thích về sample application và testcase.

Tôi đã chuẩn Web site sample: Quản lý thông tin nhân viên làm Web site đối tượng thực hiện test. Sample của Web site thì có thể download từ link sau. File thì là file war thông thường nên có thể sử dụng nếu triển khai vào Web server của môi trường thực hiện.

  • Link đến file war Ngoài ra, trường hợp import Web site sample code vào Eclipse làm project thì sử dụng file sau.

  • Link đến file zip của project

Sample Web site

Tôi sẽ giải thích đơn giản về Web site là đối tượng test đã download. Để access vào Web site thì hãy mở URL sau trên Web Browser (※ Trường hợp sử dụng server và port khác nhau thì các bạn hãy load thay thế cái phù hợp nhé.)

Web site là application có màn hình, chức năng như Bảng 1 và thực hiện di chuyển màn hình như hình 1.

Bảng 1  Khái quát màn hình và chức năng

Tên màn hình Chức năng
Danh sách nhân viên Hiển thị danh sách nhân viên
Download file thông tin nhân viên
Reset thông tin nhân viên
Di chuyển màn hình đến màn hình thay đổi thông tin nhân viên
Di chuyển màn hình đến màn hình đăng ký thông tin nhân viên
Thay đổi thông tin nhân viên Thay đổi thông tin nhân viên
Di chuyển đến màn hình danh sách thông tin nhân viên
Kết quả thay đổi thông tin nhân viên Hiển thị kết quả thay đổi thông tin nhân viên
Di chuyển đến màn hình danh sách thông tin nhân viên
Kết quả xóa thông tin nhân viên Hiển thị kết quả xóa thông tin nhân viên
Di chuyển đến màn hình danh sách thông tin nhân viên
Đăng ký thông tin nhân viên Reset thông tin nhân viên
Di chuyển đến màn hình danh sách thông tin nhân viên
Kết quả đăng ký thông tin nhân viên Hiển thị kết quả đăng ký thông tin nhân viên
Di chuyển đến màn hình danh sách thông tin nhân viên
Kết quả reset thông tin nhân viên Hiển thị kết quả reset thông tin nhân viên
Di chuyển đến màn hình danh sách thông tin nhân viên

Screenshot_1

Hình 1 Khái quát di chuyển màn hình

Tạo testcase

Tiếp theo, thực hiện test cho từng chức năng trong sample Web site đã nói ở trên.  Tôi đang nghĩ testcase đại khái sẽ như bảng 2.

Bảng 2 List testcase

No Màn hình đối tượng test Nội dung test
1 Danh sách nhân viên Confirm là nếu click ID của nhân viên trong list thông tin thì di chuyển đến màn hình Edit thông tin của nhân viên đó
2 List nhân viên, thay đổi thông tin nhân viên, kết quả thay đổi thông tin nhân viên Confirm là sau khi di chuyển màn hình theo trình tự Màn hình thay đổi thông tin nhân viên→Màn hình kết quả thay đổi→Màn hình danh sách, trường hợp thực hiện xử lý「Back」「Next」 của Web Browser thì màn hình được di chuyển đúng
3 List nhân viên Confirm nếu click button Download thông tin nhân viên thì thông tin nhân viên đang hiển thị được download bằng file CSV
4 Đăng ký thông tin nhân viên Confirm nếu đăng ký thông tin không bị lỗi bằng xử lý check khi đăng ký thông tin nhân viên thì được đăng ký bình thường
5 Đăng ký thông tin nhân viên Confirm nếu đăng ký thông tin bị lỗi do xử lý check khi đăng ký thông tin nhân viên thì error message được hiển thị, không di chuyển màn hình, được yêu cầu input lại
6 Thay đổi thông tin nhân viên Confirm nếu đăng ký thông tin không bị lỗi do xử lý check khi thay đổi thông tin nhân viên thì được thay đổi bình thường
7 Thay đổi thông tin nhân viên Confirm nếu đăng ký thông tin bị lỗi do xử lý check khi thay đổi thông tin nhân viên thì error message được hiển thị, không di chuyển màn hình mà được yêu cầu input lại
8 Thay đổi thông tin nhân viên Confirm nếu thực hiện xử lý xóa thông tin nhân viên thì thông tin nhân viên được xóa đúng
9 Thay đổi thông tin nhân viên Confirm message xác nhận được hiển thị khi thay đổi thông tin nhân viên được hiển thị đúng
10 Thay đổi thông tin nhân viên Confirm message xác nhận được hiển thị khi xóa thông tin nhân viên được hiển thị đúng

Dựa vào cách code đã giới thiệu ở bài trước và khái quát về sample, tôi sẽ giải tích cách test theo test case.

Class design

Như tôi đã giới thiệu ở bài trước, code test thì có thể viết bằng một trong 4 ngôn ngữ nhưng với sample lần này thì tôi dùngJava. Bạn hãy download code test thì từ link sau.

  • Link đến file project của code test ※ Code test đang là file project của Eclipse nên nếu import vào Eclipse có thể thực hiện test bằng Junit. Nếu để nguyên Project SeleniumWebDriver như vậy thì phát sinh lỗi đường dẫn của class nên hãy copy tất cả file jar trong folder libs và selenium-java-2.x.x.jar bên trong đã giải nén「selenium-java-2.x.x.zip」(Get từ http://seleniumhq.org/download/)vào folder 「lib」 rồi sử dụng nhé.

Liên quan đến vai trò to lớn và mối quan hệ của class thì mời các bạn tham khảo hình 2.

Hình 2 Mối quan hệ và sơ đồ class của testcase

Sample lần này sẽ là kiểu thực hiện xử lý test phụ thuộc Web Browser và xử lý test không phụ thuộc Web Browser ở class riêng biệt. Đây là phương châm design của Selenium: vì đang design để tạo driver của các Web Browser và API để có thể thực hiện test testcase trên bất kể Web Browser nào nên có thể thực hiện dễ dàng.

Tên class và vai trò thì hơi khó hiểu chút nhưng nếu chạy 6 class sau bằng Junit thì việc test sẽ được thực hiện.

  • EmployeeManagerFirefoxDriverEdit
  • EmployeeManagerFirefoxDriverRegist
  • EmployeeManagerFirefoxDriverSearch
  • EmployeeManagerChromeDriverEdit
  • EmployeeManagerChromeDriverRegist
  • EmployeeManagerChromeDriverSearch Class tên là「EmployeeManagerXxxDriverEdit」 là class test dùng cho Web BrowserXxx và dùng cho màn hình edit thông tin nhân viên,

class có tên là 「EmployeeManagerXxxDriverRegist」 là class test dùng cho Web Browser Xxx và dùng cho màn hình đăng ký nhân viên,

class có tên là「EmployeeManagerXxxDriverSearch」 là class test dùng cho Web Browser và dùng cho màn hình danh sách nhân viên.

Trình tự test

Nói chung, test Web application là kiểu「Trước hết, thực hiện thao tác đối với các yếu tố trong trang Web rồi so sánh kết quả thao tác với giá trị giả định」. Do đó, việc code class test sẽ dựa vào trình tự xử lý như sau.

【1】Xử lý reset Web Browser

Tạo object thật của org.openqa.selenium.WebDriver, sử dụng method「get(String url)」, load URL đối tượng test.

【2】Get các yếu tố đối tượng

Đối với URL đối tượng test đã load bằng「【1】Xử lý reset Web Browser」, sẽ sử dụng method WebDriver「findElement(By by) hoặc findElements(By by)」, get các yếu tố đối tượng thao tác.

【3】Thao tác đối với các yếu tố đối tượng

Thực hiện thao tác đối với các yếu tố đã get bởi「【2】Get yếu tố đối tượng」 (Trường hợp là yếu tố dùng để input thì nhập giá trị. Trường hợp là component dùng cho event trigger như button chẳng hạn thì thực hiện xử lý click).

【4】So sánh kết quả thao tác và giá trị giả định

So sánh kết quả đã thực hiện thao tác bằng「【3】Thao tác đối với yếu tố đối tượng」 và kết quả được giả định trong test. Trường hợp API đã được chuẩn bị, có thể dễ dàng get kết quả thao tác thì tự động output kết quả test bằng Junit chẳng hạn.

Trường hợp không thể lấy kết quả thao tác dễ dàng thì chụp ảnh màn hình, confirm bằng mắt sau.

【5】Xử lý cuối cùng

Close tất cả cửa sổ Web Browser là đối tượng thao tác test. Trường hợp quay lại trạng thái trước khi xử lý thực hiện test thì thực hiện xử lý back lại trạng thái trước khi thao tác test, sau đó, close tất cả cửa sổ Web Browser đối tượng thao tác test.

Coding hóa trình tự test

Giờ chúng ta hãy thử extract bên trong testcase dựa theo trình tự này nhé.

Sample code 1 là code thực hiện kết hợp testcase 6 và testcase 7 trong「Bảng 2 List testcase」.

Sample code1 EmployeeManagerEdit#editInvalidTest_21char_20char()

private void editInvalidTest_21char_20char() {

driver.get(initialURL);

driver.findElement(By.xpath("//table[@id='emptable']/tbody/tr[2]/td/a")).click(); // 【1】

// 【2】始まり

driver.findElement(By.xpath("//table[@id='edittable']/tbody/tr[2]/td[2]/input")).clear();

driver.findElement(By.xpath("//table[@id='edittable']/tbody/tr[2]/td[2]/input")).

sendKeys("テスト変更_XX#?1234567890+");

driver.findElement(By.xpath("//table[@id='edittable']/tbody/tr[3]/td[2]/input[2]")).click();

new Select(driver.findElement(By.xpath("//table[@id='edittable']/tbody/tr[4]/td[2]/select"))).

selectByVisibleText("開発部1部");

driver.findElement(By.xpath("//table[@id='edittable']/tbody/tr[5]/td[2]/input")).click();

driver.findElement(By.xpath("//div[@id='editpanel']/form/input[6]")).click();

// 【2】終わり

driver.switchTo().alert().accept(); // 【3】

// 【4】始まり

String filePath_20over = CaputureUtils.getFilePath(getClass().getName(), browserName, "editInvalidTest_21char_20char_1st");

CaputureUtils.getScreenshot((TakesScreenshot) driver, filePath_20over);

Logger logger = Logger.getLogger(getClass());

logger.info(filePath_20over + "のキャプチャ内エラー文言が「・社員名は20文字以内で入力してください。」となっていることを確認してください。");

// 【4】終わり

// 【5】始まり

driver.findElement(By.xpath("//table[@id='edittable']/tbody/tr[2]/td[2]/input")).clear();

driver.findElement(By.xpath("//table[@id='edittable']/tbody/tr[2]/td[2]/input")).

sendKeys("テスト変更_X#?1234567890+");

driver.findElement(By.xpath("//div[@id='editpanel']/form/input[6]")).click();

driver.switchTo().alert().accept();

String filePath_20 = CaputureUtils.

getFilePath(getClass().getName(), browserName, "editInvalidTest_21char_20char_2nd");

CaputureUtils.getScreenshot((TakesScreenshot) driver, filePath_20);

logger.info(filePath_20

  • "のキャプチャ内文言が「テスト変更_X#?1234567890+の情報を変更しました。」となっていることを確認してください。");

// 【5】終わり

driver.findElement(By.linkText("検索")).click(); // 【6】

}

Từng xử lý sẽ như sau.

  1. Mở màn hình danh sách nhân viên, click ID của nhân viên thứ 2 từ trên xuống
  2. Input thông tin mà sẽ thành lỗi khi thay đổi thông tin nhân viên, ấn button Thay đổi
  3. Sau khi ấn button Thay đổi, hiện ra dialog confirm nên ấn OK trên dialog confirm.
  4. Xuất hiện error message trên màn hình thay đổi thông tin nhân viên nên chụp màn hình. Xuất ra log với nội dung là confirm kết quả test bằng ảnh chụp màn hình
  5. Input giá trị không có lỗi vàothông tin nhân viên, thực hiện xử lý thay đổi. Sau khi thay đổi, chụp màn hình, xuất ra log với nội dung là confirm đóng màn hình bình thường
  6. Di chuyển đến màn hình danh sách nhân viên sau khi hoàn thành xử lý thay đổi Sample code 1 đang sử dụng class có tên là「CaputureUtils」 khi lưu ảnh chụp màn hình nhưng đây là class Util tự tạo ra.

Nội dung xử lý thì các bạn tham khảo sample code 2. Có thể lưu capture bằng cách sử dụng driver(TakesScreenshot) của Web Browser như【1】 dưới đây.

Sample code 2 CaputureUtils(Một phần)

public class CaputureUtils {

public static void getScreenshot(TakesScreenshot driver, String filePath) { // 【1】

File scrFile = driver.getScreenshotAs(OutputType.FILE);

try {

FileUtils.copyFile(scrFile, new File(filePath));

} catch (IOException e) {

Logger logger = Logger.getLogger(CaputureUtils.class);

logger.warn(e);

}

}

public static String getFilePath(String... params) {

StringBuilder builder = new StringBuilder();

builder.append("c:\tmp\");

builder.append(getYYYYMMDD());

builder.append("\screenshot\");

builder.append(getYYYYMMDD());

for (String param : params) {

builder.append("_");

builder.append(param);

}

builder.append(".png");

return builder.toString();

}

(Lược bỏ)

}

Sample code 1 đang chỉ mô tả phần không phụ thuộc vào Web Browser. Trường hợp cần thực hiện code khác nhau cho từng Web Browser thì viết codetestbằng testcase dùng cho từng Web Browser.

Ví dụ, code (Sample code 3 dưới đây) của classtestcủa màn hình Search nhân viên dùng cho Firefox đang tự thực hiện test liên quan đến download file.

Ngoài ra, liên quan đến sample code 3, hãy chú ý ngoài test liên quan đến download file, cũng có thể test「Chỉ xử lý dùng để thực hiện test common」.

Có thể nói Selenium WebDriver là ví dụ cảm quan xem API đang được design để giảm các trường hợp viết khác nhau cho từng Web Browser trong test code.

Sample code 3 Test class của màn hình search nhân viên dùng cho Firefox

package employeeManager.firefox.search;

import org.junit.Test;

import org.openqa.selenium.By;

import org.openqa.selenium.firefox.FirefoxDriver;

import employeeManager.common.search.EmployeeManagerSearch;

import employeeManager.firefox.EmployeeManagerFirefoxDriver;

/**

  • Firefoxの従業員一覧画面テスト

*/

public class EmployeeManagerFirefoxSearch extends EmployeeManagerFirefoxDriver {

private EmployeeManagerSearch employeeManagerSearch;

@Override

protected void setupProfile() {

profile.setEnableNativeEvents(true);

}

@Override

public void preTest() {

super.preTest();

employeeManagerSearch = new EmployeeManagerSearch("Firefox", getDriver(), getinitialURL());

}

// 遷移テスト

@Test

public void transitionTest() throws InterruptedException {

employeeManagerSearch.transitionTest();

}

// ダウンロードテスト

@Test

public void downloadTest() throws InterruptedException {

if (driver != null) {

driver.quit();

}

// ダウンロードするファイルの保存先フォルダを指定 0:デスクトップ 1:ダウンロードフォルダ 2:ダウンロードに指定された最後のフォルダ

profile.setPreference("browser.download.folderList", 0);

// ダウンロードするファイルの保存先フォルダが指定してあればそれを使う

profile.setPreference("browser.download.useDownloadDir", true);

// 指定したmimeタイプは有無を言わさずダウンロードする

profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream;");

// 作成したプロファイルでFirefox(のドライバー)を起動する

driver = new FirefoxDriver(profile);

driver.get(getinitialURL());

driver.findElement(By.xpath("//div[@id='downloadpanel']/form/input")).click();

Thread.sleep(3000);

}

@Test

public void exit() {

employeeManagerSearch.afterTestClass();

}

}

// ダウンロードテスト

@Test

public void downloadTest() throws InterruptedException {

if (driver != null) {

driver.quit();

}

// ダウンロードするファイルの保存先フォルダを指定 0:デスクトップ 1:ダウンロードフォルダ 2:ダウンロードに指定された最後のフォルダ

profile.setPreference("browser.download.folderList", 0);

// ダウンロードするファイルの保存先フォルダが指定してあればそれを使う

profile.setPreference("browser.download.useDownloadDir", true);

// 指定したmimeタイプは有無を言わさずダウンロードする

profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream;");

// 作成したプロファイルでFirefox(のドライバー)を起動する

driver = new FirefoxDriver(profile);

driver.get(getinitialURL());

driver.findElement(By.xpath("//div[@id='downloadpanel']/form/input")).click();

Thread.sleep(3000);

}

@Test

public void exit() {

employeeManagerSearch.afterTestClass();

}

}

Selenium WebDriver hữu ích trong thời đại SaaS

Từ code sample đã nói ở trên, tôi nghĩ các bạn có thể hiểu được việc test Web application bằng cách sử dụng Selenium WebDriver có thể thực hiện dễ dàng mà không phụ thuộc vào Web Browser.

Những năm gần đây, nhu cầu về Web application đang tăng cao như cung cấp Web application nghiệp vụ ở hình thái SaaS chẳng hạn. Ngoài ra, ở phương diện môi trường, cũng có tình trạng nhiều Web Browser như Firefox, Chrome, Internet Explorer chẳng hạn đang xung đột chia sẻ (share), Web application đòi hỏi hoạt động ổn định và mang tính common ở từng Web Browser.

Nói chung cách kiểm chứng hoạt động của Web application là thực hiện test trên nhiều Web Browser.

Ngoài ra, nếu cân nhắc đến việc phải thực hiện test giống nhau cho từng Web Browser và lặp lại cho từng lần update Web Browser thì sẽ đưa đến kết luận「Nên nhanh chóng tự động hóa việc test」.

Selenium WebDriver có thể chia phần phụ thuộc Web Browser đến mức nhỏ nhất, và có thể dễ dàng tạo test program nên sẽ đáng để chúng ta cân nhắc như là một lựa chọn vô cùng hữu ích,và như là một cách thức tạo môi trường test tự động cho Web application.

Note: Software as a Service viết tắt là SaaS, tạm dịch là phần mềm như một dịch vụ. Theo định nghĩa của hãng nghiên cứu toàn cầu IDC là: "phần mềm hoạt động trên web, được quản lý bởi nhà cung cấp và cho phép người sử dụng truy cập từ xa".

Nguồn: http://www.atmarkit.co.jp/ait/articles/1211/07/news009.html