Note: Mình đã update cách đọc file excel mới ở đây.
Nội dung bài viết
I. Mở đầu
Mình ít khi sử dụng đến cách làm này, nên cóp nhặt trên mạng đoạn code này, bạn nào dùng có thể copy thẳng vào trong project.
NOTE: Cái cách này mình ko khuyến khích nhé. Hãy dùng chức năng đọc csv của Junit5 thay thế.
Yêu cầu:
- thư viện POI của Apache.
- thư viện Common-compress Down file Jar
Giải nén và add các tất cả các file jar vào project ngoại trừ log4j.
Lưu ý là phải add cả những file jar ở trong folder /lib/ và /ooxml-lib/
Bạn nào nếu sử dụng Maven project thì add 2 cái này vào file pom.xml
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.0.0</version> </dependency>
II. Class đọc file Excel
Mình đặt cái class này ở trong package utilities.
package utilities; import java.io.FileInputStream; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.DataFormatter; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class ReadFile { private static XSSFWorkbook ExcelWBook; private static XSSFSheet ExcelWSheet; public static void setExcelFile(String path, String sheetName) throws Exception { try { // Open the Excel file FileInputStream ExcelFile = new FileInputStream(path); // Access the excel data sheet ExcelWBook = new XSSFWorkbook(ExcelFile); ExcelWSheet = ExcelWBook.getSheet(sheetName); } catch (Exception e) { throw (e); } } public static String[][] getTestData(String tableName) { String[][] testData = null; try { // Handle numbers and strings DataFormatter formatter = new DataFormatter(); XSSFCell[] boundaryCells = findCells(tableName); XSSFCell startCell = boundaryCells[0]; XSSFCell endCell = boundaryCells[1]; int startRow = startCell.getRowIndex() + 1; int endRow = endCell.getRowIndex() - 1; int startCol = startCell.getColumnIndex() + 1; int endCol = endCell.getColumnIndex() - 1; testData = new String[endRow - startRow + 1][endCol - startCol + 1]; for (int i = startRow; i < endRow + 1; i++) { for (int j = startCol; j < endCol + 1; j++) { Cell cell = ExcelWSheet.getRow(i).getCell(j); testData[i - startRow][j - startCol] = formatter.formatCellValue(cell); } } } catch (Exception e) { e.printStackTrace(); } return testData; } public static XSSFCell[] findCells(String tableName) { DataFormatter formatter = new DataFormatter(); String pos = "begin"; XSSFCell[] cells = new XSSFCell[2]; for (Row row : ExcelWSheet) { for (Cell cell : row) { if (tableName.equals(formatter.formatCellValue(cell))) { if (pos.equalsIgnoreCase("begin")) { cells[0] = (XSSFCell) cell; pos = "end"; } else { cells[1] = (XSSFCell) cell; } } } } return cells; } }
Trong class có 3 method chính:
setExcelFile
: Đọc file và xác định data ở sheet nào trong file excelfindCells
: Tìm vị trí các cell có chứa data trong sheetgetTestData
: Lấy data và lưu vào các array
III. Cách inject data vào trong các test method
1. Cấu trúc file Excel
File Excel phù hợp với Class trên có dạng như sau:
Nó sẽ được đánh dấu ở 2 góc bằng 1 từ hoặc 1 dãy ký tự nào đó (chính là method findCells ở trên). Trong ví dụ này mình sử dụng từ invalid
2. Cách lấy đường dẫn đến file linh hoạt
File data nên được đặt trong project luôn, đừng để ở vị trí nào đó ở trên máy ngoài project vì nếu có ai đó làm chung với bạn thì đường dẫn đến file sẽ bị sai. Tất nhiên là đường dẫn đến project ở mỗi máy lại khác nhau nên chúng ta phải có cách để dynamic cái đường dẫn đó để lúc nào cũng đúng dù ở bất kỳ máy nào.
Như ở trong hình: file sẽ nằm ở trong folder “data” và file có tên là “data.xlsx”. Do cái đường dẫn là cố định, không đổi nên mình sẽ đặt nó ở trong class Links (Xem lại bài 16)
public class Links { .... public static final String PATH_TO_EXCEL = System.getProperty("user.dir") + File.separator + "data" + File.separator + "data.xlsx"; }
Cái File.separator chính là cái ký tự “\” hoặc “/”, sẽ tùy vào hệ điều hành để hiển thị.
3. Thực hiện việc đọc file excel vào lúc nào?
Tùy vào mục đích sử dụng để xác định thời điểm đọc file Excel:
- Đọc file 1 lần và sẽ run trước tất cả các test
- Test nào cần data thì chỉ đọc file ở test đó.
Trong hướng dẫn lần này, mình dùng cách thứ 2 vì dễ làm :)))) Ai muốn làm cách 1 thì tự nhét cái read file vào BeforeSuite hoặc BeforeTest, tùy bạn.
Class test Login sẽ như sau:
public class LoginTest extends BaseTest { LoginPage loginPg; @Test(dataProvider="loginData") public void loginFail(String userName, String password) { loginPg = new LoginPage(driver); loginPg.login(userName, password); Assert.assertTrue(loginPg.isDisplayed()); } @DataProvider(name = "loginData") public Object[][] dataProvider() throws Exception { ReadFile.setExcelFile(Links.PATH_TO_EXCEL, "LoginTest"); Object[][] testData = ReadFile.getTestData("invalid"); return testData; } }
Trong đó: sử dụng annotation DataProdiver của TestNG để làm việc inject data vào trong method test.
Một số điểm lưu ý:
- Nếu cái dataProdiver method mà bạn đặt ở Class khác thì trên chỗ method Test bạn cần phải khai báo cái class chứa method DataProvider.
- Bắt buộc cái method Test phải có parameter trùng với số cột được định nghĩa trong file excel (ko tính 2 cái từ ở góc dùng để đánh dấu). Giả sử cái file data có thêm 1 cột nữa là email thì ở trong Method Test cũng phải có thêm parameter Email
- Không nên định nghĩa pass/fail ở trong file data vì 2 TH pass và fail sẽ có cách check kết quả khác nhau
- Càng không nên lưu pass/fail ra file excel vì bạn đã có 1 cái report của TestNG rồi, giờ còn phải mò mẫm vào file excel để xem kết quả pass fail thì quá khổ.
Và đây là kết quả sau khi run test, mình chỉ làm demo nên giá trị đầu vào nó ko đúng với tiêu chí test lắm.
IV. Tổng kết
Nhiều bạn yêu cầu bài này quá, nay mình mới cố gắng sắp xếp thời gian viết được, mong rằng đáp ứng được nhu cầu của mọi người. Nếu có thắc mắc gì thì hãy đặt lại comment nhé.
[…] [Bài 23] Đọc dữ liệu từ file Excel […]
Rất mong anh có thể thât nhanh ra sớm các bài viết nữa ạ. Em đang học và làm đến nó nên bài viết của anh thật sự rất hữu ích và cần thiết. :D. Xin chân thành cảm ơn ạ 😀
Thanks em!
Anh đang khá bận nên có thời gian anh sẽ viết thêm. Em có thể gợi ý thêm các chủ đề mà em muốn anh viết.
Em có viết testscript theo từng testcase trong file excel, và sau khi run test thì sẽ ghi PASS/FAIL vào dòng tương ứng của testcase đó trong file excel. anh viết bài hướng dẫn về cái này được không ạ . :D. Xênh kiu anh ạ
p/s: hiện tại em đang nhập tay :D.
Em còn một số trường hợp sẽ tổng hợp lại rùi nhờ anh tư vấn or có thể viết bài hướng dẫn càng tốt ạ . hi.
Hi em,
Write vào excel cũng được nhưng đó không phải là việc của automation test em ạ. Automation có report của riêng nó, nó không update vào bất cứ cái document nào.
Việc đánh giá pass/fail trong testcase em phải tự làm bằng tay thôi.
Hì, vâng ạ.
[…] là nơi để lưu file ảnh, chỗ này mình làm giống với bài 23, đọc file excel. Các bạn có thể xem […]
Anh cho e hỏi đoạn này với ạ e chưa rõ
“public static final String PATH_TO_EXCEL = System.getProperty(“user.dir”) + File.separator + “data” + File.separator + “data.xlsx”;”
user.dir là cố định ạ hay là file nào ạ ?
File.separator khi chạy thì e thay bằng “\” đúng k ạ
Hi em.
user.dir là cố định, ko cần thay đổi. File.sperator cũng là cố định, không cần thay đổi.
Ví dụ: File exel ở C:\Users\ngoc\eclipse-workspace\selenium-webdriver\data\data.xlsx
– System.getProperty(“user.dir”) là trỏ đến cái folder project, chính là “C:\Users\ngoc\eclipse-workspace\selenium-webdriver”
– File.sperator chính là “\” hoặc “/” tùy vào hệ điều hành, Window là “\”, linux và Mac là “/”. Giả sử khi cái project này được clone về máy Mac, nó được lưu ở vị trí: /Users/user/eclipse-workspace/selenium-webdriver. Nếu ta fixed cái đường dẫn theo window thì test không run được nữa.
Em có thể đọc thêm ở đây: https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
a oi cho e hỏi khi đọc dữ liệu exel mình có thể test 2 trường hợp đăng nhập thành công và không thành công thì trường hợp đăng nhập thành công mà mình điền các dữ liệu hợp lệ thì nó sẽ thông báo thành công thì làm thế nào để test NG nó thông báo là trường hợp pass ạ
Hi em, anh chưa hiểu câu hỏi của em lắm, nhưng nếu có 2 case login “thành công” và “không thành công” trong đọc file excel thì anh sẽ làm như sau:
1. Tách riêng 2 phần data ấy cho 2 test cases riêng biệt.
2. Run test case login “thành công” –> check điều kiện: URL + title page (trang home, sau khi login)
3. Run test case login “không thành công” –> check điều kiện: Error message + URL page (vẫn là trang login)
a Giang ơi khi em run loginFail thì báo “Test ignored” 🙁 a giải thích phần này cho e được k ạ. em cảm ơn
Em viết thông tin tiết kiệm thế, “Test ignored” xuất hiện ở chỗ nào? console? https://stackoverflow.com/questions/50368108/testng-test-ignored-error-message em có thể đọc tham khảo link này. Nguyên nhân là do em setup dataProvider ko đúng thôi.
Vâng là thông báo từ console ạ 🙁 em đã sửa được rồi 😀
nguyên nhân đúng là do setup dataProvider k đúng ạ
Anh cho em hỏi với ạ:
Em có 1 file excel với 20 account khác nhau
Khi e chạy script để login vào google, thì mỗi lần login xong 1 account
thì browser sẽ đóng và mở lên một browser mới cho mỗi account
Giờ làm thế nào để có thể login 20 account mà k cần phải mở browser mới vậy ạ?
Hi em, không biết em có đọc bài khác anh viết không. Anh không khuyến khích việc login 20 lần như vậy trong mỗi session, vì:
– Google hoặc App của em có thể chặn em sai 5 lần đăng nhập sai –> 15 lần còn lại sẽ bị error
– Mỗi test là độc lập và chỉ dùng 1 session duy nhất, đừng dùng chung, để đảm bảo tính independent.
– Em có thể rút ngắn thời gian run test bằng việc run parallel nhiều session độc lập, cùng lúc.
Dạ e ví dụ thôi ạ, chứ e làm là tạo account là login account ở dự án e đang làm ạ
E chạy file excel như ví dụ của anh á, mỗi lần e chạy xong 1 account là 1 tab mới hiện lên ạ.
Đúng là 1 lần chạy sẽ có 1 browser instance sẽ xuất hiện. Anw, bài này đã cũ, anh sẽ viết bài mới về đọc file csv, nhẹ nhàng hơn kiểu đọc excel rất nhiều.
Dạ e cảm ơn anh ạ, e sẽ đợi bài mới của a <3
Đây em ơi, anh đã viết xong https://giangtester.com/doc-file-csv-bang-junit5/
[…] đọc file excel như bài https://giangtester.com/bai-23-doc-du-lieu-tu-file-excel/ thì quá lằng nhằng, nặng nề, không linh […]
Anh Giang ơi, có cách nào dùng Auto Test để check Mapping tỉnh/ thành phố, quận/ huyện, phường/ xã khi Dev insert vào CSDL không ạ?
Hi em, theo anh hiểu là em cần check xem: phường A có thuộc quận B và nằm trong tỉnh C? –> dùng Auto UI cũng test được nhưng mất công.
Anh nghĩ, em dùng SQl sẽ verify nhanh hơn là dùng auto, vì cái đó là setting, chỉ insert 1 lần, ko phải thứ thay đổi liên tục để mà em phải dùng auto để check mỗi lần release.
A Giang ơi, a có mở lớp ở Hà Nội k ạ, nếu có thì mở khu vực nào…chi phí của 1 khóa auto là khoảng bn ạ, e biết java cơ bản thôi, cũng có khái niệm về lập trình… đang có nhu cầu muốn học, a tư vấn thêm cho e vs
Hi em, anh có mở lớp ở HN nhưng anh không train selenium, anh train api testing sử dụng Rest-Assured.