ĐẠI HỌC QUỐC GIA HÀ NỘI TRƯỜNG ĐẠI HỌC CÔNG NGHỆ PHẠM THỊ HẢI YẾN XÂY DỰNG ỨNG DỤNG KIỂM THỬ PHẦN MỀM TỰ ĐỘNG SỬ DỤNG SELENIUM VÀ WEBDRIVER LUẬN VĂN THẠC SĨ CÔNG NGHỆ THÔNG TIN HÀ NỘI - 2020
ĐẠI HỌC QUỐC GIA HÀ NỘI TRƯỜNG ĐẠI HỌC CÔNG NGHỆ PHẠM THỊ HẢI YẾN XÂY DỰNG ỨNG DỤNG KIỂM THỬ PHẦN MỀM TỰ ĐỘNG SỬ DỤNG SELENIUM VÀ WEBDRIVER
Ngành: Khoa học máy tính Chuyên ngành: Khoa học máy tính Mã số: 08480101.01
LUẬN VĂN THẠC SĨ CÔNG NGHỆ THÔNG TIN NGƯỜI HƯỚNG DẪN KHOA HỌC: PGS.TS. HOÀNG XUÂN HUẤN HÀ NỘI - 2020
1
LỜI CAM ĐOAN
Tôi xin cam đoan kết quả đạt được trong luận văn là sản phẩm của cá nhân tôi, thực hiện dưới sự hướng dẫn của PGS. TS Hoàng Xuân Huấn. Trong toàn bộ nội dung của luận văn, những điều được trình bày hoặc là của cá nhân hoặc là được tổng hợp từ nhiều nguồn tài liệu. Tất cả các tài liệu tham khảo đều có xuất xứ rõ ràng và được trích dẫn đúng quy định.
Tôi xin hoàn toàn chịu trách nhiệm và chịu mọi hình thức kỷ luật theo quy định
cho lời cam đoan của mình.
Hà Nội, ngày …. tháng ... năm 2020
Học viên
Phạm Thị Hải Yến
2
LỜI CẢM ƠN
Để hoàn thành luận văn này tôi xin chân thành gửi lời cảm ơn đến PGS. TS. Hoàng Xuân Huấn cùng các thầy cô trong khoa Công nghệ thông tin – Đại học Quốc Gia Hà Nội đã đóng góp ý kiến, nhận xét, quan tâm chỉ bảo và tạo cho tôi những điều kiện tốt nhất từ khi bắt đầu cho tới khi hoàn thành luận văn của mình.
Đồng thời, tôi cũng xin gửi lời cảm ơn đến gia đình, bạn bè và đồng nghiệp đã luôn quan tâm, chia sẻ, động viên và tạo mọi điều kiện để tôi có thể hoàn thành tốt mọi công việc trong quá trình thực hiện luận văn.
Mặc dù đã rất cố gắng trong quá trình thực hiện nhưng luận văn không thể tránh
khỏi những thiếu sót, tôi rất mong nhận được sự góp ý của các thầy cô và bạn bè.
Học viên
Phạm Thị Hải Yến
3
MỤC LỤC
LỜI CAM ĐOAN .......................................................................................................... 1
LỜI CẢM ƠN ................................................................................................................ 2
MỤC LỤC ...................................................................................................................... 3
DANH MỤC HÌNH VẼ ................................................................................................. 6
DANH MỤC BẢNG BIỂU ........................................................................................... 8
DANH MỤC CÁC KÝ HIỆU, CHỮ VIẾT TẮT VÀ CÁC THUẬT NGỮ .............. 9
LỜI MỞ ĐẦU .............................................................................................................. 10
CHƯƠNG 1: GIỚI THIỆU VỀ KIỂM THỬ PHẦN MỀM .................................... 12
1.1. Giới thiệu về kiểm thử phần mềm ......................................................................... 12
1.2. Phát triển hướng kiểm thử TDD (Test Driven Development) ............................ 13
1.2.1. Khái niệm ..................................................................................................... 13
1.2.2. Các cấp độ TDD ........................................................................................... 16
1.2.3. Các lỗi thường gặp khi áp dụng TDD .......................................................... 16
1.3. Phát triển hướng hành vi BDD (Behaviour Driven Development) .................... 16
1.3.1. Khái niệm ..................................................................................................... 16
1.3.2. Quy trình phát triển phần mềm truyền thống ............................................... 18
1.3.3. Quy trình phát triển theo hướng BDD ......................................................... 18
CHƯƠNG 2. GIỚI THIỆU VỀ CÔNG CỤ KIỂM THỬ TỰ ĐỘNG VÀ MÔ HÌNH THIẾT KẾ PAGE OBJECT MODEL (POM) ......................................................... 20
2.1. Công cụ kiểm thử tự động Cucumber .................................................................. 20
2.1.1. Khái niệm ..................................................................................................... 20
2.1.2. Ngôn ngữ Gherkin ........................................................................................ 20
2.1.3. Cách chạy một Cucumber Junit test ............................................................. 22
2.1.4. Chu trình ....................................................................................................... 23
2.1.5. Sơ đồ chu trình làm việc xử lý các bước trong cucumber ........................... 27
2.1.6. Cấu trúc dự án cài đặt Cucumber ................................................................. 28
2.1.7. Các thư viện sử dụng để chạy Cucumber..................................................... 28
2.2. Selenium WebDriver .............................................................................................. 29
2.2.1. Khái niệm ..................................................................................................... 29
2.2.2. Giới thiệu về đối tượng UI (Locators) ......................................................... 31
2.2.2.1. Xác định phần tử Web theo ID .......................................................... 31
2.2.2.2. Xác định phần tử Web theo Name ..................................................... 32
4
2.2.2.3. Xác định phần tử Web theo LinkText ................................................ 32
2.2.2.4.Xác định phần tử Web theo TagName ............................................... 33
2.2.2.5. Xác định phần tử Web theo ClassName ............................................ 33
2.2.2.6. Xác định phần tử Web theo CSS ....................................................... 34
2.2.2.7. Xác định phần tử Web theo Xpath .................................................... 34
2.2.3. Các thư viện sử dụng để chạy Selenium WebDriver ................................... 36
2.2.4. Các hàm xử lý chung trong Selenium WebDriver ....................................... 36
2.3. Giới thiệu mẫu thiết kế (Design pattern) .............................................................. 38
2.3.1. Khái niệm...................................................................................................... 38
2.3.2. Phân loại mẫu thiết kế (Design Pattern) ....................................................... 39
2.4. Mô hình thiết kế Page Object Model (POM) ....................................................... 41
2.4.1. Lý do chọn mô hình thiết kế Page Object Model (POM) ............................ 41
2.4.2. Mô hình thiết kế Page Object Model (POM) là gì? ..................................... 43
2.4.3. Ưu điểm của mô hình thiết kế Page Object Model (POM) .......................... 43
2.4.4. Ví dụ ............................................................................................................. 44
CHƯƠNG 3: HỆ THỐNG TÍCH HỢP LIÊN TỤC ................................................. 48
3.1. Hệ thống tích hợp liên tục (CI) .............................................................................. 48
3.1.1. Khái niệm ..................................................................................................... 48
3.1.2. Áp dụng hệ thống tích hợp liên tục .............................................................. 50
3.1.3. Lợi ích của việc tích hợp liên tục ................................................................. 50
3.1.4. Jenkins .......................................................................................................... 52
CHƯƠNG 4: THỰC NGHIỆM KIỂM THỬ TỰ ĐỘNG TẠI CÔNG TY VIVAS VÀ ĐÁNH GIÁ KẾT QUẢ ............................................................................................... 54
4.1. Phân tích hoạt động kiểm thử tại công ty trước khi áp dụng kiểm thử tự động ................................................................................................................................. 54
4.1.1. Tổng quan về công ty, sản phẩm, môi trường kiểm thử .............................. 54
4.1.2. Quy trình kiểm thử trước đây tại VIVAS .................................................... 55
4.2. Cài đặt và áp dụng kiểm thử tự động vào các dự án của VIVAS ...................... 58
4.2.1. Cấu trúc dự án .............................................................................................. 58
4.2.2. Cấu trúc mã nguồn ....................................................................................... 60
4.2.3. Tích hợp Jenkins .......................................................................................... 64
4.2.4. Báo cáo kết quả chạy kiểm thử ..................................................................... 65
4.3. Đánh giá kết quả sau khi áp dụng kiểm thử tự động vào dự án của VIVAS .... 67
5
4.3.1. Tiết kiệm thời gian ........................................................................................ 68
4.3.2. Tiết kiệm nguồn nhân lực ............................................................................. 70
4.4. Những khó khăn khi triển khai hệ thống kiểm thử tự động trong công ty VIVAS 71
4.5. Hướng phát triển tiếp theo của framework ......................................................... 72
KẾT LUẬN .................................................................................................................. 73
TÀI LIỆU THAM KHẢO ........................................................................................... 74
6
DANH MỤC HÌNH VẼ
Hình 1.1. Chu trình TDD qua màu sắc (từ trang 1minus1.com) .................................. 14
Hình 1.2. Các bước thực hiện TDD Từ trang http://agiledata.org/essays/tdd.html) .... 15
Hình 1.3. TDD kết hợp với BDD ................................................................................... 17
Hình 1.4. Chu trình làm việc kết hợp TDD và BDD ..................................................... 17
Hình 1.5. Quy trình phát triển truyền thống .................................................................. 18
Hình 1.6. Quy trình phát triển BDD .............................................................................. 19
Hình 2.1. Mã nguồn viết bằng ngôn ngữ Gherkin ......................................................... 21
Hình 2.2. Mã nguồn viết bằng ngôn ngữ Gherkin ......................................................... 21
Hình 2.3. Mã nguồn để chạy Cucumber ........................................................................ 22
Hình 2.4. Chương trình chạy kiểm thử với Cucumber .................................................. 23
Hình 2.5. Mã nguồn viết bằng ngôn ngữ Gherkin ......................................................... 24
Hình 2.6. Mã nguồn thực thi các bước trong kịch bản kiểm thử................................... 24
Hình 2.7. Kết quả chạy kịch bản kiểm thử và log khi có trường hợp sai ...................... 25
Hình 2.8. Mã nguồn thực thi các bước trong kịch bản kiểm thử................................... 25
Hình 2.9. Kết quả chạy các kịch bản kiểm thử đã đúng ................................................ 26
Hình 2.10. Chu trình làm việc trong Cucumber ............................................................ 27
Hình 2.11. Cấu trúc dự án cài đặt Cucumber ............................................................... 28
Hình 2.12. Thư viện Cucumber cần cài đặt ................................................................... 28
Hình 2.13. Sử dụng Maven để cài đặt các thư viện ....................................................... 29
Hình 2.14. Các hệ điều hành phổ biến .......................................................................... 30
Hình 2.15. 7 cách xác định phần tử Web ...................................................................... 31
Hình 2.16. Xác định phần tử Web bằng ID ................................................................... 32
Hình 2.17. Xác định phần tử Web bằng Name .............................................................. 32
Hình 2.18. Xác định phần tử Web bằng Linktext .......................................................... 33
Hình 2.19. Xác định phần tử Web bằng Tagname ........................................................ 33
Hình 2.20. Xác định phần tử Web bằng Classname ...................................................... 33
Hình 2.21. Xác định phần tử Web bằng CSS ................................................................. 34
Hình 2.22. Ví dụ minh họa cách xác định phần tử ........................................................ 34
Hình 2.23. Thư viện cần thiết để chạy Selenium WebDriver ........................................ 36
Hình 2.24. Sử dụng Maven để cài đặt các thư viện ....................................................... 36
Hình 2.25. Mã nguồn minh họa cho Selenium Webdriver ............................................ 38
Hình 2.26. Mã nguồn ví dụ cho việc chỉ sử dụng Selenium Webdriver ........................ 42
7
Hình 2.27. Cấu trúc POM ............................................................................................. 43
Hình 2.28. Cấu trúc Page Object Model ....................................................................... 44
Hình 2.29. Mã nguồn trang Đăng nhập ........................................................................ 45
Hình 2.30. Mã nguồn trong PageObjects và PageUIs của trang Đăng nhập .............. 46
Hình 2.31. Mã nguồn chạy nhiều trình duyệt ................................................................ 47
Hình 3.1. Vòng đời CI cơ bản ....................................................................................... 48
Hình 3.2. Quá trình tích hợp liên tục CI ....................................................................... 49
Hình 3.3. Hệ thống tích hợp liên tục ............................................................................. 49
Hình 3.4. 10 hệ thống CI sử dụng với GitHub .............................................................. 52
Hình 3.5. Giao diện Jenkins .......................................................................................... 53
Hình 4.1. Quy trình kiểm thử trước đây tại VIVAS ....................................................... 56
Hình 4.2. Cấu trúc dự án thực tế ................................................................................... 58
Hình 4.3. Quản lý mã nguồn bằng Github .................................................................... 59
Hình 4.4. Cấu trúc mã nguồn cài đặt thực tế ................................................................ 60
Hình 4.5. Cấu hình thông số cho Jenkins ...................................................................... 65
Hình 4.6. Báo cáo kết quả kiểm thử trên Jenkins .......................................................... 65
Hình 4.7. Biểu đồ kết quả kiểm thử trên Jenkins ........................................................... 65
Hình 4.8. Biểu đồ kết quả kiểm thử trên Jenkins ........................................................... 66
Hình 4.9. Báo cáo kết quả kiểm thử trên Extent reports ............................................... 66
Hình 4.10. Báo cáo kết quả kiểm thử trên TestNG report ............................................. 67
Hình 4.11. Biểu đồ thống kê tỷ lệ thực hiện được kiểm thử tự động ............................. 68
Hình 4.12. Biểu đồ so sánh thời gian thực thi giữa kiểm thử thủ công và tự động trên một trình duyệt ...................................................................................................................... 69
Hình 4.13. Biểu đồ so sánh thời gian thực thi giữa kiểm thử thủ công và tự động trên ba trình duyệt ...................................................................................................................... 70
Hình 4.14. Bảng so sánh nguồn lực thực hiện kiểm thử thủ công và tự động .............. 71
8
DANH MỤC BẢNG BIỂU
Bảng 2.1. Bảng chú thích lệnh trong thư mục chạy Cucumber ..................................... 23
Bảng 2.2. Bảng so sánh Selenium WebDriver và các công cụ khác ............................. 30
Bảng 2.3. Bảng phân loại Xpath ................................................................................... 35
Bảng 2.4. Một số cú pháp trong Xpath .......................................................................... 35
Bảng 2.5. Xác định phần tử sử dụng Webdriver ........................................................... 37
Bảng 2.6. Các hàm hay sử dụng trong Selenium Webdriver ........................................ 37
Bảng 2.7. 5 mẫu thiết kế trong mẫu thiết kế kiến tạo .................................................... 39
Bảng 2.8. Những mẫu thiết kế thuộc nhóm mẫu thiết kế kiến trúc ................................ 39
Bảng 2.9. Những mẫu thiết kế thuộc nhóm mẫu thiết kế hành vi .................................. 40
Bảng 4.1. Bảng thống kê số kịch bản kiểm thử của một vài dịch vụ tại Vivas .............. 57
Bảng 4.2. Bảng thống kế số kịch bản kiểm thử đã áp dụng thực tế kiểm thử tự động .. 67
Bảng 4.3. Bảng thống kê thời gian thực thi của kiểm thử thủ công và tự động ............ 68
9
DANH MỤC CÁC KÝ HIỆU, CHỮ VIẾT TẮT VÀ CÁC THUẬT NGỮ
STT
Tiếng Anh Tiếng Việt
Kiểm thử tự động Nhân viên phân tích nghiệp vụ Phát triển hướng hành vi Viết tắt AT BA BDD
1 Automation Test 2 Business Analyst 3 Behavior Driven Development
CI
Page Object Model POM
TDD
4 Continuous Integration 5 Developer 6 Maintenance 7 Manual Test 8 9 Refactor 10 Regression Test 11 Software Testing 12 Test case 13 Test Driven Development 14 Tester 15 Test script Tích hợp liên tục Lập trình viên Bảo hành, bảo trì Kiểm thử thủ công Mô hình Page Object Tái cấu trúc Kiểm thử hồi quy Kiểm thử phần mềm Trường hợp kiểm thử Phát triển hướng kiểm thử Kiểm thử viên Kịch bản kiểm thử
10
LỜI MỞ ĐẦU
Trong nhiều năm qua, tự động hóa được ứng dụng ở rất nhiều lĩnh vực nhằm giảm thời gian, nhân lực và sai sót. Ngành công nghệ thông tin mà cụ thể là phát triển phần mềm cũng không ngoại lệ. Một sản phẩm công nghệ thông tin hay phần mềm có chất lượng không thể thiếu hoạt động kiểm thử phần mềm, trong khi đó hoạt động này lại tiêu tốn và chiếm tỷ trọng khá lớn công sức và thời gian trong một dự án. Do vậy, nhu cầu tự động hoá kiểm thử phần mềm cũng được đặt ra. Việc áp dụng kiểm thử tự động hợp lý sẽ mang lại thành công cho hoạt động kiểm thử phần mềm cũng như nâng cao chất lượng của sản phẩm phần mềm. Kiểm thử tự động giúp giảm bớt công sức thực hiện, tăng độ tin cậy và rèn luyện kỹ năng lập trình cho kiểm thử viên.
Selenium là bộ kiểm thử tự động miễn phí (mã nguồn mở) dành cho các ứng dụng web trên các trình duyệt và nền tảng khác nhau. Với selenium cùng một số công cụ hỗ trợ khác như Cucumber, Jenkins, Maven,… kiểm thử viên có thể phát triển thành các framework hỗ trợ cho viết các kịch bản kiểm thử và chạy các kịch bản này một cách tự động, giảm nguồn lực, tăng độ tin cậy và nhàm chán của công việc kiểm thử.
Ngoài ra, hiện nay, nhu cầu kiểm thử tự động khá cao nhưng nhân lực trong ngành này không nhiều, đặc biệt là ở Hà Nội. Các công ty muốn áp dụng kiểm thử tự động trong quá trình phát triển dự án nhưng việc hiểu biết về kiểm thử tự động khá là mơ hồ và chưa xây dựng được một framework chuẩn áp dụng cho dự án tại công ty mình.
Dựa vào những lý do trên cùng với những kinh nghiệm 4 năm tôi có được trong lĩnh vực kiểm thử. Tôi muốn xây dựng một framework kiểm thử tự động hỗ trợ các kiểm thử viên. Đó là lý do tôi chọn đề tài “Xây dựng ứng dụng kiểm thử phần mềm tự động sử dụng selenium và webdriver”
Đề tài tìm hiểu cơ sở lý thuyết và kinh nghiệm thực tế về kiểm thử cũng như xây dựng ứng dụng kiểm thử phần mềm tự động để giảm nhân lực kiểm thử và đảm bảo chất lượng phần mềm hơn với công việc kiểm thử bằng tay.
Mục tiêu chính của đề tài bao gồm:
Đưa ra những khái niệm cơ bản về quy trình phát triển hiện nay cũng như việc áp dụng kiểm thử tự động trong quy trình phát triển phần mềm (TDD, BDD)
Đưa ra những khái niệm cơ bản về các công cụ cần thiết như: Cucumber,
Selenium, Jenkins
Đưa ra một framework nhỏ (kết hợp Cucumber và Selenium) và cách chạy
các kịch bản kiểm thử này bằng Jenkins.
Ngoài phần mở đầu, kết luận và phụ lục phần còn lại của luận văn được chia làm
4 chương, cụ thể như sau:
Chương 1 giới thiệu về kiểm thử phần mềm
11
Chương 2 giới thiệu về công cụ kiểm thử tự động và các loại mô hình thiết kế và phân tích lý do chọn cũng như ưu nhược điểm của mô hình Page Object Model (POM)
Chương 3 giới thiệu về hệ thống tích hợp liên tục và giới thiệu công cụ
Jenkins được sử dụng trong dự án thí điểm.
Chương 4 giới thiệu về công ty VIVAS và đánh giá hiệu quả của kiểm thử
tự động khi áp dụng vào dự án của công ty VIVAS.
12
CHƯƠNG 1: GIỚI THIỆU VỀ KIỂM THỬ PHẦN MỀM
Một nghiên cứu được tiến hành bởi NIST trong những năm gần đây cho biết rằng các lỗi phần mềm gây tổn thất cho nền kinh tế Mỹ một con số đáng kể, hơn một phần ba chi phí này có thể tránh được nếu việc kiểm thử phần mềm được thực hiện tốt hơn. Người ta thường tin rằng, một kiếm khuyết nếu được tìm ra sớm hơn thì chi phí để sửa chữa nó sẽ rẻ hơn. Do vậy kiểm thử phần mềm là hoạt động vô cùng quan trọng trong chu trình phát triển phần mềm ở các công ty công nghệ hiện nay.
1.1. Giới thiệu về kiểm thử phần mềm
Kiểm thử phần mềm là quá trình thực thi 1 chương trình với mục đích tìm ra lỗi. Kiểm thử phần mềm đảm bảo phần mềm đáp ứng chính xác, đầy đủ và đúng theo yêu cầu của khách hàng, yêu cầu của sản phẩm đã đặt ra. Kiểm thử có thể cung cấp cho doanh nghiệp một quan điểm, một cách nhìn độc lập về phần mềm để từ đó cho phép đánh giá và thấu hiểu được những rủi ro trong quá trình triển khai phần mềm [1].
Các mục tiêu chính của kiểm thử phần mềm:
Trong thời gian xác định trước, kiểm thử viên tìm được càng nhiều lỗi càng tốt. Đảm bảo rằng phần mềm cuối cùng phù hợp với các yêu cầu đặc tả của nó. Đo lường chất lượng của sản phẩm và dự án. Viết kịch bản kiểm thử (testcase) chất lượng cao, thực hiện kiểm thử hiệu quả
và đưa ra các báo cáo chính xác.
Kiểm thử tự động là thực hiện kiểm thử phần mềm bằng một chương trình đặc biệt với rất ít hoặc không có sự tương tác của con người, giúp kiểm thử viên không phải lặp đi lặp lại các bước nhàm chán. Trong kiểm thử tự động, có các Testscript được viết sẵn và chạy tự động để so sánh kết quả thực tế với kết quả mong đợi. Kiểm thử tự động hoạt động rất hiệu quả khi cần thực hiện các kiểm tra lặp lại và hồi quy để đảm bảo rằng một ứng dụng hoạt động chính xác sau khi có thay đổi mới. Các TestScript chạy với sự trợ giúp của các công cụ, tập lệnh và phần mềm để thực hiện các hành động được xác định trước được viết trong kịch bản kiểm thử.
Trong một số dự án, kiểm thử phần mềm chiếm khoảng trên 50% tổng giá phát triển phần mềm. Do đó một trong các mục tiêu của kiểm thử là tự động hóa kiểm thử, nhờ đó mà giảm thiểu chi phí rất nhiều, tối thiểu hóa các lỗi do người gây ra, đặc biệt giúp việc kiểm thử hồi qui dễ dàng và nhanh chóng hơn.
Ưu điểm của kiểm thử tự động
a. Tính hiệu quả trong công việc: Ưu điểm lớn nhất của kiểm thử tự động là thay thế con người lặp đi lặp lại đúng quy tắc các bước kiểm thử nhàm chán, tránh được hao phí về mặt thời gian.
b. Độ tin cậy: Dù lặp đi lặp lại nhiều lần vẫn cho ra kết quả giống nhau do vậy độ ổn
định cao, tránh được rủi ro có thể phát sinh.
13
c. Cải thiện chất lượng: Kiểm thử tự động làm giảm rủi ro về mặt chất lượng sản phẩm, việc kiểm thử được thực hiện một cách nhanh chóng. Có thể tái sử dụng các trường hợp kiểm thử.
d. Tốc độ xử lý cực nhanh: Nếu mất 5 phút để kiểm thử thủ công thì chỉ cần mất 30s
nếu sử dụng kiểm thử tự động.
e. Chi phí thấp: Việc rút ngắn thời gian và tiết kiệm nhân lực giúp cho việc kiểm thử
tự động trở nên hiệu quả.
Nhược điểm của kiểm thử tự động
a. Ban đầu thì chi phí cho kiểm thử tự động sẽ cao hơn kiểm thử thủ công b. Để kiểm thử tự động thực hiện được thì vẫn cần con người phải bỏ thời gian, công
sức và tiền bạc, ...
c. Mất chi phí cho các công cụ tự động hóa như bản quyền, bảo trì, tìm hiểu, training. d. Khó mở rộng hơn nhiều so với kiểm thử thủ công e. Yêu cầu những người có trình độ chuyên môn cao mới thực hiện được f. Số lượng công việc phải làm để mở rộng cho kiểm thử tự động sẽ nhiều và khó
hơn so với kiểm thử thủ công.
1.2. Phát triển hướng kiểm thử TDD (Test Driven Development)
1.2.1. Khái niệm
Phát triển hướng kiểm thử TDD (Test Driven Development) là một phương thức làm việc, hay một quy trình viết mã hiện đại. Lập trình viên sẽ thực hiện thông qua các bước nhỏ và tiến độ được đảm bảo liên tục bằng cách viết và chạy các bài kiểm thử tự động. Quá trình lập trình trong TDD cực kỳ chú trọng vào các bước liên tục sau:
a. Viết 1 kịch bản kiểm thử cho hàm mới. Đảm bảo rằng kiểm thử sẽ bị sai. b. Chuyển qua lập trình sơ khai nhất cho hàm đó để kiểm thử có thể đúng c. Tối ưu hóa đoạn mã nguồn của hàm vừa viết sao cho đảm bảo kiểm thử vẫn đúng
và tối ưu nhất cho việc lập trình kế tiếp
d. Lặp lại cho các hàm khác từ bước 1. Thực tế, nên sử dụng UnitTestFramework cho TDD (như JUnit trong Java), chúng ta có thể có được môi trường hiệu quả vì các kiểm thử được thông báo rõ ràng thông qua màu sắc: Đỏ: kiểm thử sai, chuyển sang viết chức năng cho kiểm thử đúng Xanh lá: viết một kiểm thử mới hoặc tối ưu mã nguồn đã viết trong màu đỏ.
Phát triển hướng kiểm thử TDD (Test-Driven Development) là kết hợp phương pháp Phát triển kiểm thử trước (Test First Development) và phương pháp Điều chỉnh lại mã nguồn (Refactoring).
Mục tiêu quan trọng nhất của TDD là nghĩ về thiết kế trước khi viết mã nguồn cho chức năng. Một quan điểm khác lại cho rằng TDD là một kỹ thuật lập trình. Nhưng nhìn chung, mục tiêu của TDD là viết mã nguồn sáng sủa, rõ ràng và có thể chạy được.
14
Hình 1.1. Chu trình TDD qua màu sắc (từ trang 1minus1.com)
Ba điều luật khi áp dụng TDD
Không cho phép viết bất kỳ một mã chương trình nào cho tới khi nó làm một kiểm
thử bị sai trở nên đúng.
Không cho phép viết nhiều hơn một kiểm thử đơn vị mà nếu chỉ cần 1 kiểm thử đơn vị cũng đã đủ để sai. Hãy chuyển sang lập trình chức năng để làm đúng kiểm thử đó trước.
Không cho phép viết nhiều hơn 1 mã chương trình mà nó đã đủ làm một kiểm thử
bị sai chuyển sang đúng.
Các bước thực hiện trong chu trình TDD
15
Hình 1.2. Các bước thực hiện TDD Từ trang http://agiledata.org/essays/tdd.html)
16
1.2.2. Các cấp độ TDD
Mức chấp nhận (Acceptance TDD (ATDD)): với ATDD thì bạn viết một kiểm thử chấp nhận đơn hoặc một đặc tả hành vi (behavioral specification) tùy theo cách gọi của bạn; mà kiểm thử đó chỉ cần đủ cho các mã chương trình sản phẩm thực hiện (đúng hoặc sai) được kiểm thử đó. Mức chấp nhận (Acceptance TDD) còn được gọi là Behavior Driven Development (BDD).
Mức lập trình (Lập trình viên TDD): với mức này bạn cần viết một kiểm thử lập trình đơn (single lập trình viên test) đôi khi được gọi là kiểm thử đơn vị mà kiểm thử đó chỉ cần đủ cho các mã chương trình sản phẩm thực hiện (đúng hoặc sai) được kiểm thử đó. Mức lập trình (Lập trình viên TDD) thông thường được gọi là TDD.Vậy nên, thực chất BDD là 1 loại TDD, và người ta thường gọi Lập trình viên TDD là TDD.
1.2.3. Các lỗi thường gặp khi áp dụng TDD
Không quan tâm đến các kịch bản kiểm thử bị sai ●
Quên đi thao tác tối ưu sau khi viết mã nguồn cho kịch bản kiểm thử đúng ●
Thực hiện tối ưu mã nguồn trong lúc viết mã nguồn cho kiểm thử đúng ●
Đặt tên các kịch bản kiểm thử khó hiểu và tối nghĩa ●
Không bắt đầu từ các kiểm thử đơn giản nhất và không theo các bước nhỏ. ●
Chỉ chạy mỗi kịch bản kiểm thử đang bị sai hiện tại ●
Viết một kịch bản kiểm thử với kịch bản quá phức tạp ●
1.3. Phát triển hướng hành vi BDD (Behaviour Driven Development)
1.3.1. Khái niệm
Phát triển hướng hành vi Behaviour Driven Development (BDD) là một quá trình phát triển phần mềm có nguồn gốc từ Test Driven Development (TDD). BDD sử dụng các ví dụ để minh họa hành vi của hệ thống được viết bằng ngôn ngữ dễ đọc và dễ hiểu đối với tất cả mọi người tham gia vào quá trình phát triển
Thay vì chờ đợi sản phẩm hoàn thành và kiểm thử, đội ngũ phát triển tham gia vào quá trình xây dựng mã nguồn với vai trò phân tích và xây dựng hệ thống kịch bản kiểm thử dưới góc độ ngôn ngữ tự nhiên dễ hiểu từ các yêu cầu (requirement). Đồng thời, họ giúp đỡ lập trình viên trong việc giải thích và đưa ra các phương án xây dựng mã nguồn mang tính thực tiễn với người dùng ngay trước khi bắt tay xây dựng. Người lập trình viên liên hệ mật thiết với người kiểm thử viên và xây dựng mã nguồn với những phương án mà kiểm thử viên cung cấp theo mô hình TDD.
17
Hình 1.3. TDD kết hợp với BDD
Hình 1.4. Chu trình làm việc kết hợp TDD và BDD
(Từ trang http://agiledata.org/essays/tdd.html)
18
1.3.2. Quy trình phát triển phần mềm truyền thống
Hình 1.5. Quy trình phát triển truyền thống
(Từ trang http://agiledata.org/essays/tdd.html)
(Từ trang BDD in action (Behavior-Driven Development for the whole software
lifecycle) - John Ferguson Smart (Foreword by Dan North))
Trong quy trình phát triển truyền thống, việc phân tích các yêu cầu (requirements) thường được tiến hành bởi chuyên viên phân tích nghiệp vụ (BA) một cách chuyên hóa và khi đến giai đoạn xây dựng (implementing phase) thì đa phần các lập trình viên tiếp xúc với các yêu cầu phần mềm dưới dạng các bản thiết kế. Họ chỉ quan tâm đến đầu vào, đầu ra (Input, Output) của tính năng mình xây dựng mà thiếu đi cái nhìn thực tiễn từ góc nhìn người dùng (end-users). Một hệ quả tất yếu là lỗi phần mềm đến từ việc sản phẩm ko tiện dụng với người dùng.
1.3.3. Quy trình phát triển theo hướng BDD
19
Hình 1.6. Quy trình phát triển BDD
(Từ trang http://agiledata.org/essays/tdd.html)
(Từ trang BDD in action (Behavior-Driven Development for the whole software
lifecycle) - John Ferguson Smart (Foreword by Dan North))
Việc ứng dụng BDD góp phần làm gần khoảng cách giữa đội ngũ thiết kế phần
mềm và sản phẩm thực tiễn, tối ưu quy trình. Cụ thể như sau:
Thông qua kịch bản kiểm thử, lập trình viên có cái nhìn trực quan về sản phẩm ngay trước khi xây dựng mã nguồn. Sản phẩm họ tạo ra chính xác và gần gũi người dùng hơn.
Phần mã nguồn được thêm vào chỉ vừa đủ để chạy thành công kịch bản kiểm thử, hạn chế dư thừa và qua đó hạn chế khả năng xảy ra lỗi trên những phần dư thừa.
Bảo đảm mã nguồn luôn phản ánh đúng và vừa đủ yêu cầu phầm mềm, hạn
chế được công sức tối ưu mã nguồn về sau.
Sau khi giới thiệu tổng quan về kiểm thử tự động cũng như ưu nhược điểm của kiểm thử tự động. Phần tiếp theo sẽ giới thiệu chi tiết những công cụ kiểm thử tự động mà luận văn đã sử dụng.
20
CHƯƠNG 2. GIỚI THIỆU VỀ CÔNG CỤ KIỂM THỬ TỰ ĐỘNG VÀ MÔ HÌNH THIẾT KẾ PAGE OBJECT MODEL (POM)
Sự thành công trong kiểm thử tự động phụ thuộc vào việc xác định đúng công cụ kiểm thử cho dự án. Có rất nhiều công cụ kiểm thử tự động với mã nguồn mở để lựa chọn, chính vì vậy việc lựa chọn công cụ nào khá là khó khăn. Việc lựa chọn công cụ kiểm thử trong luận văn này dựa trên số lượng công ty công nghệ đang sử dụng công cụ này và dựa vào tài nguyên sẵn có của công ty làm thực nghiệm. Sau đây là những công cụ đã sử dụng trong luận văn.
2.1. Công cụ kiểm thử tự động Cucumber
2.1.1. Khái niệm
Cucumber là công cụ kiểm thử tự động dựa trên việc thực thi các chức năng được mô tả dướng dạng văn bản thuần túy, hỗ trợ Behavior Driven Development (BDD), cho phép người dùng định nghĩa hành vi hệ thống với ngữ nghĩa tiếng anh thông qua cú pháp Gherkin. Cucumber hướng tới việc viết kịch bản kiểm thử mà bất kỳ ai cũng có thể hiểu cho dù họ không có chuyên môn kĩ thuật. Ví dụ như các nền tảng quen thuộc như Selenium thì thường chỉ người viết kiểm thử hoặc có kĩ năng lập trình mới hiểu được những gì đang kiểm thử, còn khách hàng hoặc các bên liên quan thì không đọc ngay mã nguồn để hiểu mà họ cần hiểu qua tài liệu.
Cucumber ban đầu được thực hiện dành riêng cho ngôn ngữ Ruby và sau đó được
mở rộng sang Java, cả Ruby và Java đều sử dụng Junit để chạy test.
2.1.2. Ngôn ngữ Gherkin
Cucumber thực thi các .feature file. Các thư mục feature chứa các đặc tả (step) thực thi, các đặc tả này được viết bằng ngôn ngữ Gherkin. Kịch bản kiểm thử đơn vị sẽ được viết trước và thể hiện nghiệp vụ, sau đó Mã nguồn mới được cài đặt để đúng qua tất cả các kịch bản đó.
Gherkin là một ngôn ngữ mà Cucumber đọc ngôn ngữ ấy chuyển thành kịch bản kiểm thử. Gherkin khá đơn giản, người đọc có thể hiểu kịch bản và hành động mà không cần biết chi tiết chúng được cài đặt như thế nào. Một feature có thể có nhiều scenario
Có hai quy tắc khi viết Gherkin:
Một thư mục Gherkin chỉ mô tả cho một tính năng Thư mục mã nguồn Gherkin là .feature
21
Ví dụ 1:
Hình 2.1. Mã nguồn viết bằng ngôn ngữ Gherkin
Ví dụ 2:
Hình 2.2. Mã nguồn viết bằng ngôn ngữ Gherkin
Trong Gherkin, mỗi dòng sẽ bắt đầu bằng từ khóa Gherkin. Dưới đây là các từ
khóa trong gherkin Feature: Tất cả các file "*.feature" được quy ước chỉ bao gồm một tính năng. Một tính năng thường gồm một danh sách các “Scenario”. Có thể viết bất cứ gì cho đến khi bắt đầu “Scenario” đầu tiên (khi dòng mới bắt đầu bằng từ “Scenario:”). Thêm vào đó, tính năng có thể bao gồm “scenario outline” và “background”
Scenario: Scenario là nòng cốt trong cấu trúc Gherkin. Mọi Scenario đều bắt đầu với từ khóa “Scenario:” theo sau bởi một tiêu đề tùy ý. Mỗi tính năng có thể có một hoặc nhiều Scenario, và mỗi Scenario bao gồm một hay nhiều bước.
Given: Được sử dụng để mô tả ngữ cảnh ban đầu của hệ thống. Mục đích của Given là đưa hệ thống vào một trạng thái đã biết trước khi sử dụng
22
(hoặc hệ thống bên ngoài) bắt đầu tương tác với hệ thống (trong bước When). Givens là điều kiện tiên quyết. Khi Cucumber thực thi bước Given, nó sẽ cấu hình hệ thống để được một trạng thái rõ ràng như là: tạo, cấu hình các đối tượng hoặc thêm dữ liệu kiểm thử vào cơ sở dữ liệu
When: Mục đích của When là để mô tả các sự kiện, hành động chính mà
người dùng sử dụng
Then: Việc sử dụng từ khóa 'then' là để xem kết quả sau hành động trong bước when. Tuy nhiên, bạn chỉ có thể xác minh những thay đổi đáng chú ý
And, But: Dùng để thể hiện có nhiều given when hoặc Then Background: Từ khóa Background giúp bạn thêm một số bối cảnh vào kịch bản. Nó có thể chứa một số bước của kịch bản, nhưng sự khác biệt duy nhất là nó nên được chạy trước mỗi kịch bản
Scenario Outline: Sử dụng giống với Scenario nhưng bắt buộc phải đi cùng
với Data Tables
Examples: Phần ví dụ minh họa | (Data Tables): Bảng dữ liệu sẽ chạy cho Scenario Outline @ (Tags): Có thể sử dụng tags để nhóm các feature và scenario lại với nhau,
không lệ thuộc vào file và cấu trúc thư mục.
# (Comments): Bắt đầu dòng bằng dấu # cho biết dòng đó là dòng comment
và không được thực thi
2.1.3. Cách chạy một Cucumber Junit test
Hình 2.3. Mã nguồn để chạy Cucumber
23
Bảng 2.1. Bảng chú thích lệnh trong thư mục chạy Cucumber
@RunWith: Khai báo TestRunner, thường là Cucumber. Các kịch bản kiểm thử
sẽ không chạy được nếu thiếu cái này.
@CucumberOptions: Định nghĩa các lựa chọn cho việc chạy kiểm thử
features: Đường dẫn đến các thư mục feature glue: Định nghĩa packages khai báo Steps trong Cucumber monochrome: Dùng để hiển thị đầu ra dễ đọc hơn dryRun: Dùng để kiểm tra tất cả các bước đã có trong Step Definition hay
chưa
plugin: Để xem báo cáo dạng pretty, xem báo cáo mặc định của cucumber
và xem các báo cáo ngoài của maven
snippets: Quy định tên hàm ở bên CucumberOption tag: Định nghĩa các scenrio nào sẽ được chạy
2.1.4. Chu trình
Hình 2.4. Chương trình chạy kiểm thử với Cucumber
24
Mô tả lại hành vi dưới dạng văn bản thuần túy (sử dụng ngôn ngữ Gherhin)
Hình 2.5. Mã nguồn viết bằng ngôn ngữ Gherkin
Định nghĩa các bước
Mỗi một bước (step) trong từ khóa gherhin sẽ có một annotation tương ứng Cucumber sử dụng các biểu thức định nghĩa ra các bước (^, $, \\d,
\"([^\"]*)\" …)
Hình 2.6. Mã nguồn thực thi các bước trong kịch bản kiểm thử
25
Chạy kịch bản kiểm thử và xem các bước kiểm thử sai
Hình 2.7. Kết quả chạy kịch bản kiểm thử và log khi có trường hợp sai
Lập trình làm cho các bước được kiểm thử đúng
Hình 2.8. Mã nguồn thực thi các bước trong kịch bản kiểm thử
Chạy lại kịch bản kiểm thử và xem những kịch bản đúng Lặp lại các bước đến khi toàn bộ các kịch bản kiểm thử đúng
26
Hình 2.9. Kết quả chạy các kịch bản kiểm thử đã đúng
27
2.1.5. Sơ đồ chu trình làm việc xử lý các bước trong cucumber
Hình 2.10. Chu trình làm việc trong Cucumber
28
2.1.6. Cấu trúc dự án cài đặt Cucumber
Hình 2.11. Cấu trúc dự án cài đặt Cucumber
2.1.7. Các thư viện sử dụng để chạy Cucumber
Danh sách các thư viện Cucumber cần cài đặt
Hình 2.12. Thư viện Cucumber cần cài đặt
Sử dụng Maven để cài đặt các thư viện trên
29
Hình 2.13. Sử dụng Maven để cài đặt các thư viện
2.2. Selenium WebDriver
Công cụ kiểm thử tự động Cucumber chỉ hỗ trợ cho kiểm thử viên và lập trình viên mô tả các hành vi của người dùng dưới dạng ngôn ngữ tự nhiên. Ngôn ngữ tự nhiên này giúp toàn thành viên trong đội phát triển cũng như khách hàng có cái nhìn chung về hệ thống mà không cung cấp thư viện để thao tác với các thành phần trên giao diện Web. Vậy làm thế nào để có thể thao tác được với các thành phần trên Web để tái hiện lại các hành vi của người dùng được mô tả bởi Cucumber. Selenium WebDriver sẽ làm được điều đó. Đây là công cụ mã nguồn mở, hoàn toàn miễn phí và cung cấp đầy đủ các thư viện thao tác trên ứng dụng Web. Framework kiểm thử tự động được xây dựng dưới đây có thể thiếu Cucumber nhưng nhất định không thể thiếu Selenium WebDriver. Do đó, có thể nói Selenium WebDriver là thành phần cốt lõi chính của framework.
2.2.1. Khái niệm
WebDriver là một khuôn khổ tự động hóa web cho phép bạn thực hiện các kiểm thử của mình trên các trình duyệt khác nhau. Nó nằm trong bộ kiểm thử tự động Selenium.
Người dùng có thể dùng miễn phí Ngôn ngữ lập trình hỗ trợ: WebDriver hỗ trợ bạn viết kịch bản kiểm thử bằng các ngôn ngữ khác nhau như Java, .NET, PHP, Python, Perl, Ruby và bạn có
30
thể sử dụng các điều kiện if else, các vòng lặp để tăng tính chính xác cho kịch bản kiểm thử.
Hỗ trợ kiểm thử trên nhiều trình duyệt khác nhau (Firefox, Chrome, Internet
Explorer, Opera, Safari)
Hỗ trợ chạy kiểm thử trên nhiều hệ điều hành khác nhau (Ubuntu, Windows,
IOS …)
Hình 2.14. Các hệ điều hành phổ biến
So sánh giữa Selenium WebDriver và các công cụ kiểm thử tự động khác
Bảng 2.2. Bảng so sánh Selenium WebDriver và các công cụ khác
Trên thị trường có khá nhiều công cụ kiểm thử Web khác nhau như Quicktest professional (QTP), công cụ của IBM. Tuy nhiên, các công cụ đó không miễn phí và có những tính năng hỗ trợ ít hơn so với Selenium. Dựa vào bảng so sánh trên, ta có thể thấy Selenium là công cụ tuyệt vời để sử dụng.
31
2.2.2. Giới thiệu về đối tượng UI (Locators)
Trong selenium, các phần tử trên web (WebPhần tử) có vai trò rất quan trọng.
Selenium hỗ trợ người dùng 7 cách để xác định các phần tử web này (Locator)
ID Name LinkText TagName ClassName Css Xpath
Hình 2.15. 7 cách xác định phần tử Web
2.2.2.1. Xác định phần tử Web theo ID
Đối với ID, đây được coi như là thuộc tính đơn nhất và ổn định nhất của hệ thống phần mềm. Nếu có thể sử dụng ID cho việc xác định UI là tốt nhất. Nhưng, tất cả chúng ta đều biết, hiếm có một nhà phát triển phần mềm nào lại chăm chỉ đến mức gắn ID cho mọi đối tượng UI. Đơn giản là vì ID không phải là một thuộc tính bắt buộc và nó không hiện thị trên giao diện nên bên viết ra phần mềm không chú ý đến nó cũng là hiển nhiên.
32
Hình 2.16. Xác định phần tử Web bằng ID
2.2.2.2. Xác định phần tử Web theo Name
Name là lựa chọn thứ hai sau ID. Tuy nhiên, thuộc tính Name đôi khi không đơn nhất. Không có một ràng buộc nào bắt Name phải đơn nhất. Đối với ID, cũng sẽ không có lỗi systax nào xảy ra nếu nhà phát triển đặt hai đối tượng UI cùng ID, nhưng nó là một lỗi về ý nghĩa. Nếu làm kiểm thử đơn vị, bạn có thể bắt lỗi này.
Hình 2.17. Xác định phần tử Web bằng Name
2.2.2.3. Xác định phần tử Web theo LinkText
Link Text - một lựa chọn không tồi nếu bạn không phải kiểm định trên hệ thống với nhiều ngôn ngữ khác nhau. Thuộc tính Link Text là không đơn nhất và cũng không ổn định. Một trang web có thể có nhiều liên kết đến một trang khác hay thay đổi từ ngữ nhưng không đổi ý nghĩa. Ví dụ: nút “Login” của chúng ta bị chuyển thành “Đăng nhập”.
33
Hình 2.18. Xác định phần tử Web bằng Linktext
2.2.2.4.Xác định phần tử Web theo TagName
Hình 2.19. Xác định phần tử Web bằng Tagname
2.2.2.5. Xác định phần tử Web theo ClassName
Hình 2.20. Xác định phần tử Web bằng Classname
34
2.2.2.6. Xác định phần tử Web theo CSS
Hình 2.21. Xác định phần tử Web bằng CSS
2.2.2.7. Xác định phần tử Web theo Xpath
Xpath là việc sử dụng những biểu thức để duyệt các node trong XML/HTML. XPath là phương thức được sử dụng nhiều nhất Dưới đây là ví dụ cấu trúc HTML của một trang web và cách dùng Xpath để
duyệt các phần tử trên trang web đó
Hình 2.22. Ví dụ minh họa cách xác định phần tử
XPath tuyệt đối (Absolute Xpath)
Bắt đầu với node gốc hoặc dấu “/”
35
Ưu điểm: tìm phần tử nhanh Nhược điểm: nếu có sự thay đổi nào giữa các node là xpath sẽ sai Ví dụ: html/body/div/form/select/option Khi có thêm một tag giữa body và div là xpath sẽ không tìm được phần tử
html/body/table/div/form/select/option
XPath tương đối (Relative Xpath)
Có thể bắt đầu ở bất kỳ node nào với dấu “//” Ưu điểm: xpath ngắn Nhược điểm: tìm phần thử lâu hơn xpath tuyệt đối Ví dụ: //select/option
Kết hợp giữa xpath tuyệt đối, tương đối
Có thể kết hợp giữa xpath tuyệt đối và tương đối Ví dụ: html//table/tbody/tr/th
Bảng 2.3. Bảng phân loại Xpath
Xpath tuyệt đối html/body/div/form/select/option
Xpath tương đối //select/option
Kết hợp html/body//select/option
Một số cú pháp khác trong Xpath
Bảng 2.4. Một số cú pháp trong Xpath
Mục đích Cú pháp Ví dụ
attribute Lấy phần tử theo //tagName[@attribute=’value //input[@id=’searchIn
thuộc tính ’] put’]
contains Lấy phần tử với thuộc //tagName[contains(@attribu //input[contains(@id,
tính chứa chuỗi bất kỳ te,’value’)] ‘searchInput’)]
starts-with Lấy phần tử với thuộc //tagName[starts- //input[starts-
with(@attribute,’value’)] with(@id, ‘s’)]
tính bắt đầu bằng chuỗi bất kỳ
and
//tagName[@attribute=’val ue’ and @attribute=’value’]
Kết hợp toán tử AND với nhiều điều kiện để lấy phần tử //input[@type=’search and ’ @id=’searchInput’]
36
or (|)
Kết hợp toán tử OR với nhiều điều kiện để //tagName[@attribute=’value or @attribute=’value’] ’ //input[@type=’search ’ or @type=’submit’]
lấy phần tử //tagName[@attribute=’value //input[@type=’search
’ | @attribute=’value’] ’| @type=’submit’]
position() Lấy phần tử theo //tagName[index] //option[1]
vị trí
2.2.3. Các thư viện sử dụng để chạy Selenium WebDriver
Danh sách các thư viện Selenium WebDriver cần cài đặt
Hình 2.23. Thư viện cần thiết để chạy Selenium WebDriver
Sử dụng Maven để cài đặt các thư viện trên
Hình 2.24. Sử dụng Maven để cài đặt các thư viện
2.2.4. Các hàm xử lý chung trong Selenium WebDriver
Xác định phần tử web sử dụng WebDriver
37
Bảng 2.5. Xác định phần tử sử dụng Webdriver
By.className Giá trị của class findElement(By.className(‘someClassName’))
attribute
By.cssSelector Xác định bằng css findElement(By.cssSelector(‘input#email’))
By.id Giá trị của id attribute findElement(By.id(‘someId’))
By.linkText Xác định phần tử bằng findElement(By.linkText(‘REGISTRATION’))
value
By.tagName name của tag findElement(By.tagName(‘div’))
By.xpath findElement(By.xpath(‘//html/body/div’)
Xác định phần tử bằng xpath
By.name name findElement(By.name(‘someName’))
Giá trị của attribute
Các hàm hay sử dụng
Bảng 2.6. Các hàm hay sử dụng trong Selenium Webdriver
Khởi tạo webdriver WebDriver driver = new FirefoxDriver();
Mở url driver.get(baseUrl);
Khởi tạo webelement WebElement
element=driver.findElement(By.className(‘someClassName’))
driver.findElement(By.className(‘someClassName’)).click()
Nhấn vào một phần tử
driver.findElement(By.className(‘someClassName’)).sendkey(‘test’)
Điển dữ liệu vào textbox
driver.navigate().refresh()
Làm mới một trang web
Trở lại trang trước đó driver.navigate().back()
trang driver.navigate().forward()
Chuyển đến khác
Đóng trình duyệt driver.close() or driver.quit()
Tạm dừng Thread.sleep(5000);
38
Ví dụ
Hình 2.25. Mã nguồn minh họa cho Selenium Webdriver
2.3. Giới thiệu mẫu thiết kế (Design pattern)
2.3.1. Khái niệm
Định nghĩa của Christopher Alexander:
“Mỗi mẫu mô tả một vấn đề xảy ra lặp đi lặp lại, và trình bày trọng tâm của giải pháp cho vấn đề đó, theo cách mà bạn có thể dùng đi dùng lại hàng triệu lần mà không cần phải suy nghĩ.”
Phân tích và thiết kế là những việc đầu tiên cần phải làm khi bắt tay vào sản xuất phần mềm. Một thiết kế tốt sẽ giúp chúng ta tránh phải chỉnh sửa nhiều lần. Một người thiết kế hướng đối tượng có kinh nghiệm thường cho rằng rất khó để cho ra một thiết kế chuẩn ngay từ lần đầu, mà nó thường phải trải qua nhiều lần tái sử dụng và chỉnh sửa sau mỗi lần. Nếu nhớ được chi tiết về vấn đề trước đây và cách giải quyết nó, chúng ta có thể tái sử dụng thay vì phải sáng tạo lại. Nhưng giả sử chúng ta không nhớ rõ thì bắt buộc phải tìm lại tài liệu, tìm giải pháp mới,... Đó chính là lý do design pattern ra đời, nhiệm vụ của nó chỉ đơn giản là cô đọng lại giải pháp hiệu quả để giải quyết một vấn đề cụ thể thành một mẫu thiết kế có thể tái sử dụng.
Về giới thiệu chung, một mẫu có 4 thành phần chính:
Tên: được dùng để mô tả vấn đề thiết kế, giải pháp, và kết quả trong từ 1 đến 2
chữ.
39
Vấn đề mà mẫu này được áp dụng. Giải pháp: mô tả những thành phần tạo nên thiết kế, mối quan hệ, trách nhiệm và
cộng tác giữa các thành phần đó
Cuối cùng là hệ quả, là lợi ích cũng như hạn chế khi sử dụng mẫu. Mặc dù những điều này không được nhắc đến khi chúng ta ra quyết định thiết kế, nhưng rõ ràng việc đánh giá và hiểu được chi phí cũng như lợi ích khi áp dụng mẫu là cần thiết.
2.3.2. Phân loại mẫu thiết kế (Design Pattern)
Mẫu thiết kế được chia thành 3 loại, bao gồm: Mẫu thiết kế kiến tạo (creational pattern), mẫu thiết kế kiến trúc (structural pattern) và mẫu thiết kế hành vi (behavioral pattern)
Mẫu thiết kế kiến tạo (Creational Patterns)
Những mẫu thuộc nhóm này trừu tượng hóa quá trình khởi tạo. Chúng giúp việc tạo và trình diễn đối tượng độc lập với hệ thống. Nhóm này bao gồm 5 mẫu thiết kế, cụ thể là:
Bảng 2.7. 5 mẫu thiết kế trong mẫu thiết kế kiến tạo
Tên Mục đích
Abstract Cung cấp một giao diện cho việc tạo lập các đối tượng mà không cần xác Factory định lớp cụ thể tạo mỗi đối tượng
Builder Tách rời việc xây dựng một đối tượng phức tạp khỏi biểu diễn của nó sao cho cùng một tiến trình xây dựng có thể tạo được các biểu diễn khác nhau.
Factory Định nghĩa giao diện để sinh ra đối tượng nhưng để cho lớp con quyết Method định lớp nào được dùng để sinh ra đối tượng
Prototype Qui định loại của các đối tượng cần tạo bằng cách dùng một đối tượng mẫu, tạo mới nhờ vào sao chép đối tượng mẫu này.
Singleton Đảm bảo 1 lớp chỉ có 1 instance và cung cấp 1 điểm truy xuất toàn cục đến nó
Mẫu thiết kế kiến trúc (Structural Patterns)
Những pattern thuộc nhóm này liên quan đến việc thiết lập và định nghĩa quan hệ
giữa các đối tượng. Bao gồm:
Bảng 2.8. Những mẫu thiết kế thuộc nhóm mẫu thiết kế kiến trúc
Mục đích Tên
Adapter Chuyển giao diện của một lớp thành giao diện phù hợp yêu cầu
40
Tên Mục đích
Bridge Tách rời ngữ nghĩa của một vấn đề khỏi việc cài đặt
Composite Tổ chức các đối tượng theo cấu trúc phân cấp dạng cây, các đối tượng trong cấu trúc được thao tác theo một cách thuần nhất như nhau.
Decorator Gán thêm trách nhiệm cho đối tượng vào lúc chạy (thêm chức năng cho class).
Facade Cung cấp một interface cấp cao, dễ dùng cho một tập hợp các interface của hệ thống con (subsystem)
Flyweight Chia sẻ trạng thái chung nhằm thao tác hiệu quả tài nguyên và bộ nhớ
Proxy Cung cấp đối tượng đại diện cho một đối tượng khác để hỗ trợ hoặc kiểm soát quá trình truy xuất đến đối tượng đó
Mẫu thiết kế hành vi (Behavioral Patterns)
Nhóm này liên quan đến việc thực hiện các hành vi của đối tượng. Bao gồm:
Bảng 2.9. Những mẫu thiết kế thuộc nhóm mẫu thiết kế hành vi
Tên Mục đích
Chain of cho phép truyền request thông qua một chuỗi đối tượng nhận request Responsibility
Command mỗi request hoặc command được đóng gói và gửi đi như một đối tượng
Interpreter Hỗ trợ việc định nghĩa biểu diễn văn phạm và bộ thông dịch cho một ngôn ngữ
Iterator Truy xuất các element của đối tượng dạng tập hợp tuần tự (list, array, …)
Mediator Định nghĩa một đối tượng để điều hướng việc giao tiếp giữa một số đối tượng với nhau.
Memento chỉnh sửa và phục hồi trạng thái bên trong của đối tượng mà vẫn không vi phạm việc đóng gói dữ liệu
41
Mục đích Tên
Observer
Định nghĩa sự phụ thuộc một-nhiều giữa các đối tượng sao cho khi một đối tượng thay đổi trạng thái thì tất cả các đối tượng phụ thuộc nó cũng thay đổi theo.
State Cho phép một đối tượng thay đổi hành vi khi trạng thái bên trong của nó thay đổi
Strategy
đóng gọi các thuật toán bằng các lớp, mỗi thuật toán có thể thay đổi độc lập đối với chương trình sử dụng thuật toán. Cung cấp một họ giải thuật cho phép client chọn lựa linh động một giải thuật cụ thể khi sử dụng.
Template Method Định nghĩa phần khung của một thuật toán, tức là một thuật toán tổng quát gọi đến một số phương thức chưa được cài đặt trong lớp cơ sở; việc cài đặt các phương thức được ủy nhiệm cho các lớp kế thừa.
Visitor
Cho phép định nghĩa thêm phép toán mới tác động lên các element của một cấu trúc đối tượng mà không cần thay đổi các lớp định nghĩa cấu trúc đó.
2.4. Mô hình thiết kế Page Object Model (POM)
2.4.1. Lý do chọn mô hình thiết kế Page Object Model (POM)
Dưới đây là một kịch bản kiểm thử đơn giản kiểm tra chức năng đăng nhập vào
hệ thống không thành công do bỏ trống thông tin bắt buộc.
42
Hình 2.26. Mã nguồn ví dụ cho việc chỉ sử dụng Selenium Webdriver
Theo kịch bản trên, để kiểm tra chức năng login vào hệ thống thất bại, ta cần tìm các phần tử web (elements) và thực hiện hành động (action) để nhập giá trị vào các phần tử.
Đây chỉ là một kịch bản kiểm thử nhỏ, khá đơn giản. Việc bảo trì (maintenance) khá dễ dàng. Nhưng khi số lượng kịch bản kiểm thử tăng lên rất nhiều. Các kịch bản kiểm thử có thể sử dụng chung một chức năng để làm đầu vào. Nếu có bất kỳ sự thay đổi nào trên trang đăng nhập, ta sẽ phải thay đổi tất cả các scripts có liên quan đến trang đăng nhập. Như vậy làm theo cách trên thì số lượng mã nguồn sẽ tăng lên, sẽ có rất nhiều mã nguồn thừa, trùng lặp và việc bảo trì mã nguồn cũng khó khăn và mất nhiều thời gian hơn.
Có một giải pháp tối ưu hơn là tạo ra các lớp (class) riêng biệt. Lớp này chỉ chứa các phần tử và các phương thức tác động lên phần tử đó. Lớp này có thể được sử dụng lại trong tất cả các scripts. Khi có bất kỳ thay đổi nào, ta chỉ cần cập nhật ở một lớp duy nhất.
Cách này được gọi là Page Object Model (POM). Nó làm cho mã nguồn dễ đọc
hơn, dễ bảo trì hơn và dễ sử dụng lại hơn.
43
Hình 2.27. Cấu trúc POM
2.4.2. Mô hình thiết kế Page Object Model (POM) là gì?
POM là một mẫu thiết kế (Design Pattern) có các đặc điểm sau:
Page Object Model (POM) là một mẫu thiết kế để tạo kho lưu trữ đối tượng -
Object Repository cho các phần tử giao diện web.
Dưới mô hình này, mỗi trang web trong ứng dụng đang viết có thể tương ứng
với một lớp.
Lớp trang này sẽ chứa các phần tử web của trang web đó và cũng chứa các
phương thức thực hiện các thao tác trên các phần tử web đó.
Các phương thức này nên được đặt tên như là nhiệm vụ (task) mà chúng sẽ thực hiện. Nó rất dễ dàng ánh xạ với các hành động (actions) xảy ra trong giao diện với người dùng. Ví dụ, Nếu muốn nhập tên đăng nhập cho textbox user trên một trang, tên phương thức đó có thể là “setUserName”.
2.4.3. Ưu điểm của mô hình thiết kế Page Object Model (POM)
Tránh sự lặp lại nhiều lần trong mã nguồn. Do đó, Mô hình này sẽ trở nên dễ
dàng hơn trong việc bảo trì và tái sử dụng.
Các kho lưu trữ là độc lập với các kịch bản kiểm thử. Vì vậy, chúng ta có thể sử các kho lưu trữ giống nhau cho các mục đích khác nhau với những tool khác nhau. Ví dụ, chúng ta có thể tích hợp POM với TestNG/JUnit để kiểm tra chức năng và cùng lúc với JBehave/Cucumber để kiểm tra chấp nhận.
Mã nguồn ít hơn và được tối ưu hóa vì các phương thức trang có thể tái sử dụng
trong các lớp POM.
44
Chúng ta có định nghĩa tên phương thức tương ứng với một hoạt động cụ thể, ví dụ hành động truy cập vào trang chủ, tên phương thức giống như 'gotoHomePage()'.
2.4.4. Ví dụ
Cấu trúc dự án sẽ như sau:
Hình 2.28. Cấu trúc Page Object Model
Cấu trúc của dự án bao gồm các phần:
- Testcases: Chứa danh sách các kịch bản kiểm thử - TestData: Chứa những dữ liệu sử dụng cho dự án - Actions: Gồm những hàm chung dùng cho dự án và các hàm định nghĩa các hành
động của kịch bản kiểm thử Interfaces: Chứa danh sách địa chỉ các phần tử trên web
- - Resources: Chứa những tệp cấu hình chạy dự án và các tệp hỗ trợ
Mã nguồn trang Đăng nhập
45
Hình 2.29. Mã nguồn trang Đăng nhập
Kịch bản kiểm thử phần trang đăng nhập nằm trong thư mục testcases
46
Hình 2.30. Mã nguồn trong PageObjects và PageUIs của trang Đăng nhập
Các hàm định nghĩa các hành động và danh sách các địa chỉ phần tử trên web của kịch bản kiểm thử trang đăng nhập
Mã nguồn chạy nhiều trình duyệt:
47
Hình 2.31. Mã nguồn chạy nhiều trình duyệt
Chạy kịch bản kiểm thử trang đăng nhập với nhiều trình duyệt khác nhau.Ví dụ:
Chrome, FireFox,…
Sau khi đã xây dựng framework thành công, công việc vận hành framework hết sức quan trọng. Phần tiếp theo luận văn trình bày về hệ thống tích hợp liên tục dùng để vận hành hệ thống.
48
CHƯƠNG 3: HỆ THỐNG TÍCH HỢP LIÊN TỤC
3.1. Hệ thống tích hợp liên tục (CI)
3.1.1. Khái niệm
Martin Fowler định nghĩa như sau:
“Continuous Integration là một thực hành trong phát triển phần mềm trong đó các thành viên của một đội tích hợp công việc của họ một cách thường xuyên, thường thì mỗi người sẽ tích hợp ít nhất là hàng ngày - dẫn tới có nhiều tích hợp trong một ngày. Mỗi sự tích hợp sẽ được kiểm định lại bởi một build tự động (bao gồm cả kiểm thử) để phát hiện ra lỗi tích hợp càng sớm càng tốt. Nhiều người nhận thấy rằng hướng làm việc này giúp giảm thiểu đáng kể các vấn đề khi tích hợp và cho phép một đội phát triển có thể viết phần mềm nhanh hơn.”
Tự động hoá việc build, kiểm thử và triển khai có thể làm giảm bớt nhiều vấn đề thường gặp trong các dự án. Có một phương pháp đáng tin cậy trong việc tích hợp những thay đổi thường xuyên hơn giúp bạn đảm bảo rằng có thể tìm thấy lỗi sớm hơn sau này - CI chính là giải pháp.
Vòng đời CI cơ bản:
Hình 3.1. Vòng đời CI cơ bản
49
Hiểu đơn giản, tích hợp liên tục gồm 4 bước
Quản lý Mã nguồn Biên dịch mỗi khi có thay đổi Kiểm thử bản build mới Thông báo kết quả đến cho các lập trình viên
Hình 3.2. Quá trình tích hợp liên tục CI
Dưới đây là một hệ thống tích hợp liên tục
Hình 3.3. Hệ thống tích hợp liên tục
50
Các lập trình viên thực hiện các ticket và đẩy mã nguồn lên thư mục nơi sẽ lưu
giữ mã nguồn của dự án.
Hệ thống CI sẽ lắng nghe và thực hiện kéo mã nguồn về (server CI), build rồi
kiểm thử mã nguồn.
Trong trường hợp build, kiểm thử thất bại, các thành viên trong đội sẽ nhìn thấy ngay được lỗi phát sinh và các lập trình viên sẽ chịu trách nhiệm sửa lỗi và đẩy mã nguồn sửa lỗi đó lên nơi lưu trữ.
3.1.2. Áp dụng hệ thống tích hợp liên tục
Quản lý Mã nguồn Tự động hóa quy trình build
Quá trình build được thực hiện tự động bằng các đoạn script cài sẵn Thực hiện thường xuyên Tạo ra các script khác nhau để có thể chạy trên nhiều môi trường khác nhau Công cụ: Ant, Maven... Tạo bản build bao gồm kiểm thử
Chèn các kiểm thử vào chương trình Nhận dạng Mã nguồn có khả năng phát sinh lỗi (kiểm thử mã nguồn) Công cụ: JUnit, HtmlUnit Cam kết những thay đổi mỗi ngày Lấy Mã nguồn về nơi lưu trữ (mainline) Mỗi khi mã nguồn có thay đổi sẽ build lại (mainline) thông qua build server Kiểm thử tự động
Được thực hiện bằng các đoạn script viết sẵn Thực hiện sau khi build xong Thực hiện trong quá trình lập trình viên build trên máy của họ hoặc vào lúc
CI server build mainline
Báo cáo kết quả cho lập trình viên hoặc những thành viên liên quan
3.1.3. Lợi ích của việc tích hợp liên tục
Giảm rủi ro tích hợp: làm việc trên các dự án có nghĩa là nhiều người đang làm việc trên các task riêng biệt hoặc các phần của mã nguồn. Càng nhiều người, sự tích hợp càng nguy hiểm. Tùy thuộc vào vấn đề thực sự tồi tệ như thế nào, việc sửa lỗi và giải quyết vấn đề có thể gây ra phiền phức và có nghĩa là có nhiều thay đổi đối với mã nguồn. Thực hiện tích hợp hàng ngày hoặc thậm chí thường xuyên hơn có thể giúp giảm thiểu các loại vấn đề này ở mức tối thiểu.
Chất lượng mã nguồn cao hơn: Không cần phải lo lắng về các vấn đề xảy ra và tập trung nhiều hơn vào các tính năng của hệ thống giúp viết ra sản phẩm có chất lượng cao hơn.
51
Mã nguồn trên version control luôn hoạt động: Nếu cam kết phần nào đó làm hỏng việc build, đội phát triển sản phẩm sẽ nhận ra điều này ngay lập tức, và vấn đề sẽ được giải quyết trước khi mã nguồn bị kéo lỗi về
Giảm tranh luận gay gắt trong đội ngũ phát triển sản phẩm: Có một hệ thống
khách quan tại chỗ giúp giảm tần suất cãi nhau giữa các thành viên
Giúp thành viên kiểm thử giảm phiền phức: Có nhiều phiên bản và build của mã nguồn giúp chia cắt và tìm kiếm lỗi một cách hiệu quả, giúp công việc của đội kiểm thử dễ dàng hơn.
Giảm thời gian triển khai: Triển khai dự án là một công việc rất nhàm chán và
tốn thời gian, và việc tự động hoá quá trình này là rất cần thiết
Tăng sự tự tin và tinh thần: công việc không hiệu quả nếu luôn thường trực nỗi sợ làm hỏng cái gì đó, và họ có xu hướng tạo ra kết quả tốt hơn và có thể tập trung năng lượng làm việc hơn nếu không phải lo lắng về những hậu quả có thể xảy ra từ hành động của họ.
Circle CI
Jenkins
AppVeyor
CodeShip
Drone
Semaphore CI
Buildkite
Wercker
TeamCity
Trên Github đã có rất nhiều công cụ CI như:
52
Hình 3.4. 10 hệ thống CI sử dụng với GitHub
3.1.4. Jenkins
Jenkins là một công cụ đại diện cho khái niệm CI (continuous integration).
Jenkins giúp việc tự động chạy các script. Nó xây dựng và kiểm tra phần mềm liên tục theo dõi việc thực hiện và tình trạng của các công việc từ xa, làm cho các thành viên và người dùng dễ dàng hơn để có được mã nguồn ổn định mới nhất.
Ta muốn cả bộ UT/test chạy mỗi ngày vào 9h sáng. Mỗi ngày nhóm trưởng đến kiểm tra dữ liệu lịch sử để biết có bao nhiêu kịch bản đang sai, bao nhiêu lỗi, quản lý theo từng ngày, ta hoàn toàn có thể dùng test framework + cronjob. Tuy nhiên Jenkins cung cấp 1 giao diện trực quan hơn, biểu đồ, báo cáo phần trăm, mã nguồn đang kiểm tra, v.v ... hoàn toàn tự động, có thể kết nối theo svn hoặc git. Jenkins cũng có rất nhiều plugin và hỗ trợ hầu hết các test framework.
53
Hình 3.5. Giao diện Jenkins
Trên đây là phần giới thiệu về kiểm thử phần mềm cũng nhưng tổng quan về các công cụ đã sử dụng trong luận văn. Tuy nhiên từ lý thuyết đi đến thực hành tác giả gặp nhiều khó khăn và thách thức trong phần cài đặt. Phần tiếp theo tác giả trình bày chi tiết về cách xây dựng framework cũng như đánh giá phần thực nghiệm tại công ty VIVAS.
54
CHƯƠNG 4: THỰC NGHIỆM KIỂM THỬ TỰ ĐỘNG TẠI CÔNG TY VIVAS VÀ ĐÁNH GIÁ KẾT QUẢ
4.1. Phân tích hoạt động kiểm thử tại công ty trước khi áp dụng kiểm thử tự động
4.1.1. Tổng quan về công ty, sản phẩm, môi trường kiểm thử
VIVAS chuyên nghiên cứu và phát triển các giải pháp tối ưu cho doanh nghiệp, hợp tác với nhiều nhà cung cấp hàng đầu thế giới, đem đến cho thị trường đa dạng các dịch vụ viễn thông và giải trí.
Kết hợp giữa việc phân tích toàn diện hoạt động kinh doanh của doanh nghiệp và nhiều năm kinh nghiệm về các giải pháp công nghệ cao, mục tiêu của VIVAS là thấu hiểu và mang lại những giá trị gia tăng cho khách hàng thông qua việc tiên phong nghiên cứu và phát triển các giải pháp tối ưu góp phần giảm đáng kể chi phí đầu tư, nguồn lực, thời gian đồng thời nâng cao hiệu quả kinh doanh cho các doanh nghiệp trong kỷ nguyên công nghệ hiện nay.
Các sản phẩm của công ty:
Giải pháp cung cấp dịch vụ - OTT Communication Platform
OTT Communication là một nền tảng OTT giúp cung cấp cuộc gọi VoIP chất lượng cao (bao gồm thoại và video) và tin nhắn (nhắn tin văn bản, chia sẻ đa phương tiện) thông qua 3G/4G & Wifi. Điểm nổi bật của OTT communication platform là các nhóm tính năng SMS Out và Call Out giúp cho mọi cuộc trò chuyện không bị gián đoạn.
Giải pháp cung cấp dịch vụ - Multimedia Streaming Platform
Multimedia Streaming Platform là giải pháp cho phép các doanh nghiệp có thể quản lý, kinh doanh và phân phối nội dung Truyền hình, Video, Radio, Âm nhạc, Phim… đến người dùng một cách tập trung và đạt chất lượng tốt nhất. Với giải pháp Multimedia Streaming Platform, các nhà cung cấp dịch vụ có thể rút ngắn tương đối thời gian triển khai dịch vụ, tiết kiệm chi phí đầu tư và được đảm bảo bởi đội ngũ kỹ thuật support 24/7 giàu kinh nghiệm của VIVAS.
Dịch vụ SMS BRANDNAME
Dịch vụ tin nhắn thương hiệu (SMS Brandname) giúp doanh nghiệp triển khai các chiến dịch quảng cáo, chăm sóc khách hàng đến hàng triệu người trong một khoảng thời gian ngắn. Thương hiệu của doanh nghiệp sẽ tiếp cận đến khách hàng một cách nhanh nhất.
Dịch vụ Network - Content Delivery Network
Content Delivery Network là mạng lưới gồm nhiều máy chủ lưu trữ đặt tại nhiều vị trí địa lý khác nhau, cùng làm việc chung để phân phối nội dung đến người dùng cuối một cách nhanh nhất, tin cậy và bảo mật nhất với chi phí tối ưu. Giải pháp cho phép người
55
dùng cuối được kết nối tự động đến máy chủ lưu trữ gần nhất về mặt địa lý, thay vì phải kết nối tới máy chủ gốc của Content Provider.
Công ty liên tục có kế hoạch cải tiến sản phẩm và tính năng hiện tại đồng thời tạo ra các sản phẩm và tính năng mới. Mỗi khi một sản phẩm hay tính năng mới nào được xuất bản ra ngoài thị trường, sản phẩm và tính năng đó và những sản phẩm và tính năng cũ đều phải được tiến hành kiểm thử trên các môi trường mà sản phẩm đó hỗ trợ.
Các ứng dụng được phát triển và cài đặt trên các môi trường khác nhau
Hệ điều hành: Windows, Android, IOS … Trình duyệt: IE, Firefox, Chrome … Môi trường: Dev, Staging, Production, …
4.1.2. Quy trình kiểm thử trước đây tại VIVAS
VIVAS trước đây sử dụng kiểm thử thủ công hoàn toàn. Trong kiểm thử thủ công, kiểm thử viên sẽ kiểm thử tất cả các tính năng thiết yếu của ứng dụng hoặc phần mềm. Kiểm thử viên thực hiện các kịch bản kiểm thử và tạo báo cáo kiểm thử mà không cần sự trợ giúp của bất kỳ công cụ kiểm thử phần mềm tự động nào. Đây là một phương pháp kiểm thử cổ điển, giúp tìm lỗi trong các hệ thống phần mềm, thường được tiến hành bởi một kiểm thử viên có kinh nghiệm và thực hiện theo quy trình kiểm thử phần mềm.
56
Môi trường Dev: - Kiểm thử trên các trình duyệt: Chrome, FireFox, IE,... - Kiểm thử trên nhiều kênh: Web, Android, iOS, ... - Kiểm thử nhiều vòng khi có lỗi: Round 1, round 2,... - Kiểm thử ảnh hưởng khi thêm/sửa/xóa 1 tính năng
Môi trường Staging: - Kiểm thử trên các trình duyệt: Chrome, FireFox, IE,... - Kiểm thử trên nhiều kênh: Web, Android, iOS, ... - Kiểm thử nhiều vòng khi có lỗi: Round 1, round 2,... - Kiểm thử ảnh hưởng khi thêm/sửa/xóa 1 tính năng
Môi trường Production: - Kiểm thử trên các trình duyệt: Chrome, FireFox, IE,... - Kiểm thử trên nhiều kênh: Web, Android, iOS, ... - Kiểm thử nhiều vòng khi có lỗi: Round 1, round 2,... - Kiểm thử ảnh hưởng khi thêm/sửa/xóa 1 tính năng
Kiểm thử nghiệm thu khách hàng: - Kiểm thử trên các trình duyệt: Chrome, FireFox, IE,... - Kiểm thử trên nhiều kênh: Web, Android, iOS, ... - Kiểm thử nhiều vòng khi có lỗi: Round 1, round 2,... - Kiểm thử ảnh hưởng khi thêm/sửa/xóa 1 tính năng
Hình 4.1. Quy trình kiểm thử trước đây tại VIVAS
Theo như sơ đồ trên, trước khi bất kỳ một tính năng nào được thêm/sửa/xóa/nâng cấp và đưa ra thị trường đều phải kiểm thử qua 4 môi trường. Trong mỗi môi trường đều phải kiểm thử trên nhiều trình duyệt, nhiều kênh và trải qua nhiều vòng kiểm thử.
57
Số lượng kịch bản kiểm thử cho mỗi dự án (như TVOD, SMSMKT, SMSBRN, VasDealer, IPCamera …) có thể giao động từ 100 đến khoàng 1000 trường hợp kiểm thử cho mỗi môi trường, mỗi trình duyệt và mỗi vòng. Dưới đây là một số thống kê về số lượng kịch bản kiểm thử của một vài chức năng trong hệ thống. Số lượng này tính theo một môi trường (Ví dụ: môi trường Staging+Firefox+Web+Round 1)
Bảng 4.1. Bảng thống kê số kịch bản kiểm thử của một vài dịch vụ tại Vivas
Số lượng Kịch bản Dịch vụ kiểm thử
TVOD 1092
SMSMKT 1038
VasDealer 832
IPCamera 420
PlayBox 126
Viettalk 783
… …
Để kiểm thử cho tất cả ứng dụng, hệ điều hành, trình duyệt và cơ sở dữ liệu khác nhau, số lượng kịch bản kiểm thử sẽ rất lớn. Bên cạnh đó phải kiểm thử cả những phần ảnh hưởng khi thêm/sửa/xóa một tính năng mới. Có thể thấy nguồn nhân sự cho kiểm thử hồi quy (Regression test) và các kiểm thử cho tính năng mới sẽ rất mất thời gian và chi phí.
Từ những khó khăn của kiểm thử thủ công, tôi đã xây dựng Framework tích hợp điểm mạnh của BDD- Cucumber-Selenium-CI để hỗ trợ quá trình kiểm thử, build dự án, phát hành sản phẩm với chất lượng tốt hơn. Nhằm mục đích tiết kiệm nguồn lực, chi phí và thời gian. Đồng thời giảm sự nhàm chán của công việc kiểm thử thủ công hiện nay của công ty.
Dưới đây là kết quả cài đặt, chạy thử và đánh giá kết quả của framework tại công
ty VIVAS
58
4.2. Cài đặt và áp dụng kiểm thử tự động vào các dự án của VIVAS
4.2.1. Cấu trúc dự án
Hình 4.2. Cấu trúc dự án thực tế
Framework kiểm thử tự động
Framework sử dụng Maven Apache để khởi tạo dự án, biên dịch, đóng gói, chạy kiểm thử… một cách tự động và nhanh chóng. Trong đó thư mục pom.xml là nơi chứa các thông tin cần thiết định nghĩa một dự án như tên dự án, phiên bản, nhóm phát triển, các thư viện được sử dụng, các plugins
Cucumber: bao gồm các package, lớp, hàm sử dụng thư viện Cucumber để định
nghĩa ra các thư mục feature và các bước trong thư mục feature
Selenium WebDriver: bao gồm các package, lớp, hàm sử dụng thư viện của
Selenium WebDriver để thao tác với các đối tượng web trên trình duyệt Các hàm Cucumber và Selenium WebDriver sẽ tương tác hỗ trợ lẫn nhau Mã nguồn của framework sẽ được đẩy lên github
59
Hình 4.3. Quản lý mã nguồn bằng Github
Jenkins
Jenkins là nơi cấu hình các job để chạy kịch bản kiểm thử Có thể cấu hình các job chạy định kỳ Mỗi job trên jenkin sẽ lấy mã nguồn từ github về và dùng lệnh maven để
chạy các kịch bản kiểm thử
60
4.2.2. Cấu trúc mã nguồn
Hình 4.4. Cấu trúc mã nguồn cài đặt thực tế
src/main/java: Xây dựng các thư viện chung bao gồm các pageObjects, page
UIs, thư viện các hàm xử lý các hành động chung
src/main/resources: Chứa các thư mục cấu hình cho dự án dùng trong cucumber src/test/java: Chứa các kịch bản kiểm thử để chạy src/test/resources: Chứa các feature file, file chạy Mã nguồn của dự án: https://github.com/phamthihaiyen/maven_TVOD_SP
Xây dựng framework từ Selenium webdriver
Cốt lõi của framework là xây dựng những hàm dùng chung cho toàn bộ dự án. Ta cần tương tác với ứng dụng bằng cách sử dụng một số hành động cơ bản hoặc thậm chí một số hành động người dùng nâng cao bằng cách tạo các hàm do người dùng định nghĩa mà không có lệnh nào được xác định trước. Dưới đây là các loại hành động khác nhau:
- Tương tác Text Box - Tương tác Radio Button - Tương tác Drop Down
61
- Tương tác CheckBox - Kéo và thả, Thao tác với bàn phím - Thao tác chuột - Chọn nhiều hạng mục
Một số hàm dùng chung cơ bản của framework như
Nhấn vào 1 phần tử web
public void clickToElement(WebDriver driver, String locator) { element = driver.findElement(By.xpath(locator)); element.click();
}
Nhập giá trị cho 1 phần tử web
public void sendkeyToElement(WebDriver driver, String locator, String value) { element = driver.findElement(By.xpath(locator)); element.sendKeys(value);
}
Chọn 1 giá trị trong danh sách với mã nguồn cơ bản
element = driver.findElement(By.xpath(locator)); select = new Select(element); select.selectByVisibleText(itemText);
public void selectItemInDropdown(WebDriver driver, String locator, String itemText) { }
Chọn 1 giá trị trong danh sách với mã nguồn tùy chỉnh
String ExpectedText) throws Exception {
element = driver.findElement(By.xpath(parentdropdownlocator)); ((JavascriptExecutor)
Thread.sleep(1000);
WebDriverWait driverwait = new WebDriverWait(driver, 3000); driverwait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(B
public void selectItemInCustomDropdown(WebDriver driver, String parentdropdownlocator, String allItemDropdown, driver).executeScript("arguments[0].click();", element); y.xpath(allItemDropdown))); elements = driver.findElements(By.xpath(allItemDropdown)); for (int i = 0; i < elements.size(); i++) { String ItemText = elements.get(i).getText();
62
((JavascriptExecutor)
} break;
}
if (ItemText.equals(ExpectedText)) { ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", elements.get(i)); Thread.sleep(1000); if (elements.get(i).isDisplayed()) { elements.get(i).click(); } else { driver).executeScript("arguments[0].click();", elements.get(i)); }
}
Một số hoạt động của con trỏ chuột
element = driver.findElement(By.xpath(locator)); action = new Actions(driver); action.moveToElement(element).perform();
}
element = driver.findElement(By.xpath(locator)); action = new Actions(driver); action.doubleClick(element).perform();
}
public void hoverMouseToElement(WebDriver driver, String locator) { public void doubleClickToElement(WebDriver driver, String locator) { public void rightClick(WebDriver driver, String locator) { element = driver.findElement(By.xpath(locator)); action = new Actions(driver); action.contextClick(element).perform();
}
Một số hàm hỗ trợ giao diện trong framework
public void highlightElement(WebDriver driver, String locator) { element = driver.findElement(By.xpath(locator)); javascriptExecutor = (JavascriptExecutor) driver; String originalStyle = element.getAttribute("style");
63
javascriptExecutor.executeScript("arguments[0].setAttribute(arguments[1]
"border: 5px solid yellow; border-style: dashed;");
try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }
javascriptExecutor.executeScript("arguments[0].setAttribute(arguments[1]
, arguments[2])", element, "style", , arguments[2])", element, "style", originalStyle);
}
Sử dụng framework đã xây dựng để kiểm thử
Trong hàm nhấn vào nút thay đổi mật khẩu cần sử dụng hàm chung
Sau khi xây dựng được các hàm dùng chung, toàn bộ những kiểm thử viên có thể sử dụng hàm này trong những lớp pageObject. Tất cả các lớp pageObject đều dùng tính kế thừa từ AbstractPage trong ngôn ngữ Java. public class AccountInformationPageObject extends AbstractPage { } Ví dụ: clickToElement() đã xây dựng bên trên như sau:
public void clickToChangePasswordButton() { waitForElementVisible(driver,
AccountInformationPageUI.CHANGE_PASSWORD_BUTTON);
clickToElement(driver,
AccountInformationPageUI.CHANGE_PASSWORD_BUTTON);
}
Trong hàm điền giá trị vào ô nhập mật khẩu cũ cần sử dụng hàm chung
inputToOldPasswordTextbox () đã xây dựng bên trên như sau:
public void inputToOldPasswordTextbox(String value) { waitForElementVisible(driver,
AccountInformationPageUI.OLD_PASSWORD_TEXTBOX);
sendkeyToElement(driver,
AccountInformationPageUI.OLD_PASSWORD_TEXTBOX, value);
}
64
4.2.3. Tích hợp Jenkins
Dự án có sử dụng Maven để chạy kiểm thử tích hợp giữa Selenium/Cucumber và
Jenkins
65
Hình 4.5. Cấu hình thông số cho Jenkins
Trong phẩn quản lý mã nguồn cần điển đầy đủ thông tin đường dẫn lưu trữ mã nguồn và tài khoản đăng nhập vào nơi lưu trữ mã nguồn. Tiếp theo cần điền cú pháp chạy mã nguồn trên command gồm cú pháp mvn clean và mvn test
4.2.4. Báo cáo kết quả chạy kiểm thử
Báo cáo trên Jenkins
Hình 4.6. Báo cáo kết quả kiểm thử trên Jenkins
Báo cáo kết quả kiểm thử trên Jenkins: Cho biết kết quả kiểm thử đúng hay sai của
từng kịch bản kiểm thử và từng vòng kiểm thử
Hình 4.7. Biểu đồ kết quả kiểm thử trên Jenkins
66
Hình 4.8. Biểu đồ kết quả kiểm thử trên Jenkins
Báo cáo mở rộng
Hình 4.9. Báo cáo kết quả kiểm thử trên Extent reports
Ngoài báo cáo trên Jenkins có sẵn, kiểm thử viên có thể tích hợp thêm báo cáo mở rộng để nhìn kết quả kiểm thử dạng biểu đồ hình tròn trực quan hơn. Đồng thời báo cáo lấy được cả thông tin về thiết bị dùng để kiểm thử.
Báo cáo TestNG
67
Hình 4.10. Báo cáo kết quả kiểm thử trên TestNG report
Đây là báo cáo đơn giản và dễ hiểu nhất trong các báo cáo. Nhìn vào báo cáo TestNG, đội phát triển có thể dễ dạng biết kiểm thử viên đã kiểm thử trên trình duyệt nào với thời gian bao lâu và kết quả kiểm thử đúng/sai bao nhiêu phần trăm.
4.3. Đánh giá kết quả sau khi áp dụng kiểm thử tự động vào dự án của VIVAS
Hiện tại chúng tôi đã viết kịch bản kiểm thử cho khoảng 72% số lượng kịch bản kiểm thử và đã áp dụng thực tế cho một vài dịch vụ của VIVAS gồm: TVOD, SMSBRN, SMSMKT, VasDealer. Sau đây là những con số thống kê cho dịch vụ TVOD:
Bảng 4.2. Bảng thống kế số kịch bản kiểm thử đã áp dụng thực tế kiểm thử tự động
Tổng số Kịch bản kiểm thử 1092
Kịch bản kiểm thử có thể làm tự động 774
Số kịch bản kiểm thử đã làm tự động 446
Số kịch bản kiểm thử chưa làm tự động 328
Từ thống kê trên, ta dễ dàng nhận thấy tỷ lệ phần trăm số kịch bản kiểm thử kiểm thử thủ công hoàn toàn được thay thế bằng kiểm thử tự động lên đến 71%. 29% còn lại buộc phải có yếu tố con người như kiểm thử giao diện, thói quen người dùng, …
68
KỊCH BẢN KIỂM THỬ
Kịch bản kiểm thử không làm được tự động; 318; 29%
Kịch bản kiểm thử làm được tự động; 774; 71%
Hình 4.11. Biểu đồ thống kê tỷ lệ thực hiện được kiểm thử tự động
Thống kê thực tế về thời gian (tính theo manday) khi thực hiện kiểm thử thủ công và kiểm thử tự động trên một trình duyệt của từng môi trường khi kiểm thử toàn trình dự án
Bảng 4.3. Bảng thống kê thời gian thực thi của kiểm thử thủ công và tự động
4.3.1. Tiết kiệm thời gian
Như vậy, nếu chỉ kiểm thử trên một trình duyệt với mẫu thống kê là 446 kịch bản kiểm thử thì kiểm thử thủ công ban đầu tốn rất ít thời gian chỉ cần 9 ngày làm việc, trong khi kiểm thử tự động cần 58,5 ngày làm việc. Tuy nhiên khi số môi trường kiểm thử và số vòng kiểm thử càng tăng thì thời gian dành cho kiểm thử thủ công tăng lên nhanh
69
chóng trong khi kiểm thử tự động lại không cần quá nhiều thời gian cho việc chạy lại bộ TestScript.
Kiểm thử tự động và thủ công với một trình duyệt
120
100
75
80
58,50
60
c ệ i v m à l
61,50
y à g N
40
20
9
0
0
5
15
20
10 Vòng chạy kiểm thử
Manual Linear (Manual)
Automation Linear (Automation)
Hình 4.12. Biểu đồ so sánh thời gian thực thi giữa kiểm thử thủ công và tự động trên
một trình duyệt
Vậy bài toán hoàn hảo cho kiểm thử phần mềm là ta phải kiểm thử trên mọi trình duyệt, mọi môi trường, mọi hệ điều hành có thể. Như vậy thời gian mà kiểm thử tự động tiết kiệm được so với kiểm thử thủ công là rất đáng kể. Biểu đồ bên dưới thể hiện thời gian dành cho kiểm thử tự động và kiểm thử thủ công khi thực thi kiểm thử trên ba trình duyệt khác nhau.
70
Kiểm thử tự động và thủ công với ba trình duyệt
350
300
225
250
200
c ệ i v m à l
150
y à g N
100
67,5
58,50
50
27
0
0
5
15
20
10 Vòng chạy kiểm thử
Manual Linear (Manual)
Automation Linear (Automation)
Hình 4.13. Biểu đồ so sánh thời gian thực thi giữa kiểm thử thủ công và tự động trên ba
trình duyệt
4.3.2. Tiết kiệm nguồn nhân lực
Kiểm thử tự động không chỉ giúp doanh nghiệp tiết kiệm thời gian, mà còn giúp tiết kiệm nguồn lực vào giai đoạn kiểm thử. Với mẫu thống kê là 446 kịch bản kiểm thử được giao cho đội gồm 5 kiểm thử viên. Ta có những bài toán so sánh như biểu đồ bên dưới. Nếu chỉ có một nhân viên kiểm thử làm 446 kịch bản kiểm thử trong bốn môi trường, ba trình duyệt, mỗi môi trường kiểm thử bốn vòng thì kiểm thử thủ công sẽ mất 191 ngày làm việc còn kiểm thử tự động chỉ mất 63 ngày làm việc. Bài toán tiết kiệm nguồn lực sẽ thể hiện được khi có sự tham gia từ hai tester trở lên. Trong kiểm thử thủ công số nguồn lực tham gia vào dự án phải làm việc song song trong toàn bộ quá trình kiểm thử. Tuy nhiên, với kiểm thử tự động thì số nguồn lực chỉ phải tham gia song song trong quá trình viết TestScript. Sau đó đội kiểm thử viên sẽ rút được nguồn lực chỉ còn một người thực hiện chạy TestScript và bảo trì cho bộ TestScript đó.
71
Nguồn lực cho Kiểm thử tự động và thủ công
6
5
4
3
2
1
c ự l
0
0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200
n ồ u g N
-1
-2
-3
-4
-5
-6
Ngày làm việc
Hình 4.14. Bảng so sánh nguồn lực thực hiện kiểm thử thủ công và tự động
Với việc triển khai kiểm thử tự động, các kịch bản kiểm thử có thể chạy qua đêm (ngoài giờ làm việc) và có thể chạy trên nhiều server khác nhau, thời gian để một kiểm thử viên kiểm tra kết quả các các kịch bản chỉ mất khoảng 2-3 ngày làm việc cho một môi trường kiểm thử. Đặc thù của các dự án của VIVAS là thường xuyên phải nâng cấp dự án vào ban đêm nhằm đảm bảo độ ảnh hưởng là ít nhất đối với người dùng thật. Như vậy kiểm thử tự động, đặc biết là Jenkins đem lại hiệu quả cực kì cao với VIVAS.
4.4. Những khó khăn khi triển khai hệ thống kiểm thử tự động trong công ty VIVAS
Việc tìm nhân lực vừa có kỹ năng kiểm thử vừa có kỹ năng lập trình gặp khó khăn bởi nhiều bạn nhân viên kiểm thử có kỹ năng kiểm thử tốt nhưng tư duy lập trình không tốt, các bạn có kỹ năng lập trình tốt thì không muốn làm kiểm thử.
Khi một tính năng có nhiều sự thay đổi về cách tổ chức UI thì mất nhiều thời gian
để bảo trì mã nguồn của framework.
Kiểm thử tự động sẽ chỉ có hiệu quả cao nhất đối với dự án dài, cần kiểm thử hồi quy nhiều. Các dự án ngắn, đòi hỏi hoàn thành dự án sớm thì việc triển khai kiểm thử tự động sẽ không hiệu quả.
72
4.5. Hướng phát triển tiếp theo của framework
Xây dựng thêm phần DataDriven trong framework. DataDriven giúp cho hệ thống có thể đọc được dữ liệu đầu vào từ hệ thống quản lý thư mục hoặc từ một hệ quản trị cơ sở dữ liệu bất kỳ
Cải tiến framework để hỗ trợ cho các bạn kiểm thử không có kỹ năng lập trình
có thể sử dụng dễ dàng hơn.
Hiện tại framework chỉ đang hỗ trợ kiểm thử Web. Mục tiêu nghiên cứu tiếp theo của tác giả là tìm hiểu và ứng dụng để kiểm thử API testing, App Mobile testing cho công ty VIVAS
73
KẾT LUẬN
Cách mạng công nghiệp lần thứ tư đánh dấu kỷ nguyên vạn vật kết nối Internet. Nó xảy ra dựa trên sự hội tụ của nhiều công nghệ trong đó có công nghệ cốt lõi có công nghệ thông tin với sự phát triển không ngừng của công nghệ Internet từ thời kỳ kết nối nội dung như email đến mạng xã hội, Internet vạn vật, Internet kết nối thiết bị máy móc kết nối quá trình vận hành của các nhà máy. Hiện nay, nền công nghiệp 4.0 đang phát triển mạnh mẽ, kéo theo sự phát triển của rất nhiều ngành nghề, đặc biệt là ngành công nghệ thông tin. Do đó, yêu cầu về nhân lực trong mảng này cũng đòi hỏi các ứng viên cần phải có kỹ năng tốt hơn nữa về lập trình, các kỹ năng về tự động hóa....
Từ đây, có thể thấy được nhu cầu nhân lực có kiến thức và kinh nghiệm về kiểm thử tự động là rất lớn. Do đó, đề tài về kiểm thử tự động sẽ là tiềm năng lớn cho tương lai của mảng kiểm thử nói riêng và công nghệ thông tin nói chung.
Trong quá trình tìm hiểu và nghiên cứu, luận văn đã đưa ra những khái niệm và hướng áp dụng của Selenium và các công cụ liên quan khác trong kiểm thử phần mềm. Dựa vào kết quả nghiên cứu và áp dụng kiểm thử tự động tại công ty VIVAS, tôi thấy rằng việc ứng dụng selenium và các công cụ liên quan trong các dự án phần mềm là hoàn toàn khả thi. Do thời gian có hạn, tôi chỉ đưa ra một framework cơ bản nhất để có thể áp dụng và chạy thử nghiệm luôn, framework vẫn còn nhiều phần cần phải cải tiến và cập nhật thêm (ví dụ: DataDriven, Dynamic Locator, tốc độ chạy các kịch bản kiểm thử). Việc cải tiến framework sẽ được nghiên cứu và cập nhật trong thời gian tới.
74
TÀI LIỆU THAM KHẢO
Tiếng Anh
1. John Ferguson Smart (2014), BDD in action (Behavior-Driven Development for
the whole software lifecycle), Manning Publications.
2. Dima Kovalenko (2014), Selenium Design Patterns and Best Practices book,
Publication City/Country Birmingham, United Kingdom.
3. Mr Navneesh Garg (2014), Test Automation using Selenium WebDriver with
Java.
4. Mark Collin (2015), Mastering Selenium WebDriver, Packt Publishing. 5. Mr. Pinakin Ashok Chaubal (2018), Page Object Model using Selenium
WebDriver & Java book, Independently published.
6. David Burns (2012), Selenium 2 Testing tools Beginner’s Guide book.
Website
http://www.guru99.com/ 1.
http://www.softwaretestinghelp.com/ 2.
http://en.wikipedia.org/wiki/Test-driven_development 3.
http://agiledata.org/essays/tdd.html 4.
5. https://viblo.asia/newest