Cùng với sự phát triển nhanh chóng của công nghệ ngày nay, thì việc hướng tới sự gia tăng tốc độ và tần suất release sản phẩm tới khách hàng là một mục tiêu tất yếu của hầu hết các tổ chức, dự án phần mềm. Trong đó, việc giảm thời gian thực thi cho hệ thống test automation cũng là một yếu tố quan trọng để chúng ta hướng tới mục tiêu đó. Và để giảm thời gian test thì cũng có rất nhiều giải pháp đã được sinh ra, trong số đó không thể không nói đến các kỹ thuật để hỗ trợ thực thi test song song hay còn gọi là parallel testing.
Parallel testing là gì?
Parallel testing là việc thực hiện nhiều test cases đồng thời trên cùng một môi trường hoặc nhiều môi trường khác nhau. Ngược lại với test tuần tự là tại một thời điểm chỉ có một test case được thực thi test.
Parallel testing mang lại giá trị gì?
Giá trị lớn nhất và rõ ràng nhất là tiết kiệm được thời gian thực thi test. Giả sử bạn có 100 test cases nếu thực thi song song với 10 test case tại một thời điểm thì thời gian thực thi test đã giảm được 10 lần.
Nếu thực hiện test automation một cách tuần tự cho nhiều môi trường như: devices, OS, browser, version of product thì thời gian test sẽ rất dài. Và khả năng cao là chúng ta buộc phải giảm bớt môi trường test để rút ngắn thời gian test. Nhưng nếu parallel testing giải quyết được vấn đề thời gian test thì chúng ta vẫn có thể đảm bảo thực hiện test trên nhiều môi trường.
Phát hiện bugs sớm hơn, để Dev team có thể fix bug kịp thời trước khi release.
Tạo điều kiện để mở rộng hệ thống, khi chúng ta không còn lo ngại về mặt thời gian chạy test thì có thể thoải mái để triển khai thêm nhiều loại test, develop thêm nhiều test cases mà không lo ngại việc hệ thống automation trở nên nặng nề, chậm chạp.
Tăng motivation cho Dev team. Bạn hãy tưởng tượng, mỗi lần thực thi test automation phải mất khoảng 6-7 tiếng để hoàn thành. Dev team phải chờ một khoản time lâu như vậy để có kết quả test thì thật sự cũng cũng không mấy happy. Và parallel testing có thể làm tốt việc gỡ bỏ rào cản này.
Parallel testing có những nhược điểm gì?
Tốn nhiều tài nguyên để thực thi test như Ram, CPU. Phải thực hiện trên nhiều thiết bị nên tốn khá nhiều cost về mặt môi trường để thực thi test.
Hệ thống parallel testing sẽ rất dễ trở nên không ổn định nếu chúng ta làm không tốt việc tổ chức data, sắp xếp test case để thực thi test.
Đòi hỏi người triển khai cần có kiến thức nhất định về sản phẩm cũng như hệ thống CI.
Khi nào thì nên triển khai parallel testing?
Có hai trường hợp thường được triển khai parallel testing:
- Số lượng test case cần thực thi nhiều dẫn đến thời gian test dài ra. Vậy thời gian thực thi test bao lâu thì nên bắt đầu triển khai parallel testing? con số này tuỳ thuộc vào sự mong muốn và thống nhất trong team, tổ chức, có thể là 5 phút, 10 phút hoặc dài hơn.
- Khi một ứng dụng cần được test trên nhiều môi trường: browsers, Operating Systems, hoặc thiết bị… Chúng ta cũng nên lên kế hoạch để triển khai parallel testing.
Triển khai parallel testing như thế nào?
Tôi xin lấy một ví dụ về cách triển khai parallel testing ở Cybozu Việt Nam, một hệ thống test automation đã được triển khai từ vài năm trước và đang được mở rộng hằng ngày.
Cross-browser testing
Bộ test case bao gồm hơn 100 test cases trên browser EDGE, Firefox, Chrome và hệ điều hành Window, dưới đây là giải pháp:
Mô hình này là sự kết hợp giữa Jenkins (một công cụ để triển khai hệ thống CI) và Selenium Grid. Tuỳ theo nhu cầu mà chúng ta có thể tăng số lượng Node lên để tăng số lượng Instances lên, ví dụ: hệ thống hiện tại đang sử dụng 10 instances ở mỗi Node và tổng thời gian thực thi test là 20 phút. Nếu chúng ta vẫn muốn giảm thời gian thực thi test xuống còn 10 phút, thì có thể tăng số instances ở mỗi node lên 20 hoặc tăng thêm Node (mỗi Node 10 instances). Về chi tiết cấu hình Selenium Grid như thế nào thì chúng ta có thể tham khảo bài: Hướng dẫn cài đặt Selenium Grid 3 trên Windows
Functional and API testing
Đối với loại test này nếu chúng ta không cần run trên nhiều môi trường nhiều browser nên có thể run trên Chrome với nền tảng Docker để tận dụng thế mạnh của công nghệ ảo hóa dựa trên các containers.
Docker có thể được triển khai trên các công cụ CI khác nhau, ngoài Jenkins thì CircleCI cũng giải quyết được bối cảnh này, chúng ta có thể tham khảo mô hình bên dưới:
Với CircleCI thì chúng ta có thể tạo ra N containers (N tuỳ theo khả năng xử lý của CircleCI server), mỗi container chúng ta có thể hiểu như một Selenium Node và có thể thực thi một hoặc nhiều test case đồng thời trong mỗi container và tất nhiên mỗi container này cũng sẽ được run song song cùng nhau như bên dưới:
Các hình minh hoạ ở trên được trích lược từ hướng dẫn Parallel testing với CircleCI, các bạn có thể follow theo các bước trong bài viết này để tiến hành cấu hình nhé: Running Tests in Parallel - CircleCI
Dưới đây là mô hình triển khai ở Cybozu:
Để cấu hình được mô hình này với CircleCI bạn có thể thực hiện theo bên dưới trong file config.yml:
functional-test:
parallelism: 10
docker:
- image: circleci/node:12.22.5
- image: selenium/hub:3.141.59-20210913
name: hub
auth:
username: $DOCKER_HUB_USER
password: $DOCKER_HUB_TOKEN
- image: selenium/node-chrome:3.141.59-20210913
name: chrome
auth:
username: $DOCKER_HUB_USER
password: $DOCKER_HUB_TOKEN
environment:
TZ: Asia/Tokyo
HUB_PORT_4444_TCP_ADDR: hub
HUB_PORT_4444_TCP_PORT: 4444
NODE_NUMBER: 2
NODE_MAX_INSTANCES: 4
NODE_MAX_SESSION: 4
SCREEN_WIDTH: 1920
SCREEN_HEIGHT: 1200
steps:
- run:
name: Run test
command: |
#list-specs.js contains an array of filenames
specs=$(node ./list-specs.js | circleci tests split | tr '\n' ' ' | sed -e 's/,$//')
npm test -- wdio.conf.js --spec ${specs}
Những điểm cần lưu ý để parallel testing hoạt động ổn định
Có cách xử lý riêng những test case phụ thuộc
Cần có cơ chế riêng cho những test case có liên hệ phụ thuộc hay nói cách khác là nó sẽ ảnh hưởng đến những test case khác.
Ví dụ:
- Case-01: Verify the user can disable the Comment feature successfully.
- Case-02: Verify the user can post a Comment successfully
Ở ví dụ trên thì nếu hai test case này run đồng thời thì sẽ có khả năng Case-02 sẽ failed vì Case-01 đã disable tính năng Comment.
Đối với những test case phụ thuộc như vậy chúng ta có thể xử lý để nó thực thi test đồng thời với những case còn lại nhưng trên một môi trường riêng (ví dụ testing site riêng hoặc device riêng).
Hạn chế sử dụng hard code data
Việc sử dụng hard code data cũng là một trong những nguyên nhân chính làm cho hệ thống test automation trở nên bất ổn định. Để minh chứng cho điều đó, các bạn hãy xem một ví dụ với hai test cases sau:
-
Case-01:
- User A post a comment with content: “Hello Parallel testing”.
- Verify the content is correct.
-
Case-02:
- User B post a comment with content: “Hello Parallel testing”.
- Delete posted comment.
Nếu hai cases này được thực thi đồng thời thì sẽ có trường hợp User B delete post của User A hoặc, User A verify nội dung post của User B.
Để hạn chế việc này thì chúng ta nên sử dụng random data có thể được tạo ra từ kỹ thuật Data generator
Hai cases trên có thể được viết lại như sau:
-
Case-01:
- User A post a comment with content: “Hello Parallel testing - abc”.
- Verify the content is correct.
-
Case-02:
- User B post a comment with content: “Hello Parallel testing - xyz”.
- Delete posted comment.
Có cơ chế quản lý test data hiệu quả
Quản lý test data hiệu quả cũng là một trong những yếu tố quan trọng giúp hệ thống test automation ổn định hơn, dưới đây là hai cách tiếp cận phổ biến.
-
Các test data nên được xoá đi sau mỗi test case để tránh làm cho data bị chồng lấn lên nhau khi run nhiều test case cùng lúc. Ví dụ: một ứng dụng hiển thị bảng, chỉ cho hiển thị được tối đa 10 record, nếu không delete data sau mỗi test record thì có khả năng những test case sau sẽ failed.
-
Mỗi test case nên được test bởi một user riêng biệt.
Ví dụ: Một ứng dụng đặt lịch họp, User A có thời gian rảnh từ 10-11h- Case-01: đặt lịch họp cho User A từ 10-11h, sau đó xoá lịch họp.
- Case-02: đặt lịch họp cho User A từ 10-11h, sau đó edit và update lịch họp.
Trong ví dụ trên nếu run test đồng thời hai case này thì xác suất cao là một trong hai case sẽ failed.
-
Những dữ liệu có tính unique nên được sử dụng riêng cho mỗi test case.
Ví dụ: Một ứng dụng đặt lịch họp, mỗi phòng họp chỉ được đặt khi nó chưa được sử dụng- Case-01: đặt lịch họp cho User A, dùng phòng họp 01
- Case-02: đặt lịch họp cho User B, dùng phòng họp 01
Trong ví dụ trên nếu run test đồng thời hai case này thì xác suất cao là một trong hai case sẽ failed vì có khả năng hai lịch họp này bị trùng giờ và dùng cùng phòng họp. Trong trường hợp này thì dữ liệu “phòng họp” có tính unique, những test data này nên được tạo riêng cho mỗi test case.
Xem xét thực hiện Parallel testing tới mức độ nào
Một trong những điểm hạn chế lớn của việc thực hiện parallel testing là rất tốn tài nguyên của hệ thống. Trên cùng một máy tính, nếu chúng ta thực hiện quá nhiều tiến trình xử lý của browser thì máy sẽ rất dễ bị chậm hoặc crashing, và dẫn đến kết quả test không ổn định. Vậy nên, chúng ta cần theo dõi và tính toán xem khả năng chịu tải của cấu hình máy tính (thông số CPU, Ram) bạn đang sử dụng là bao nhiêu để điều chỉnh số lượng tuyến trình parallel testing cho phù hợp. Cùng một cấu hình của máy tính thì chỉ số thời gian test và số lượng parallel session sẽ tỉ lệ nghịch với nhau.
Ví dụ: Với máy tính có cấu hình Ram-16GB, CPU-8 luồng xử lý thì chỉ nên thực hiện run parallel 8 test case cùng một thời điểm.
Kết
Trên đây là một số góc nhìn về triển khai parallel testing cho hệ thống test automation. Điều quan trọng nhất khi bạn triển khai parallel testing vào các hệ thống CI là đảm bảo được quá trình run test một cách ổn định nhất, hạn chế tối đa các lỗi về môi trường như performance của test server, làm cho response time chậm, cũng như xung đột về data dẫn đến có nhiều Flaky test. Hậu quả của điều đó là chúng ta lại tốn thêm cost để debug và maintain cho hệ thống test automation.