Về cơ bản, khi viết các file test robot, thì nhiều khi cũng không thể nào tuân theo cấu trúc logic của test case manual
Ví dụ: Chúng ta có một Test Case tên là : User Successfully Login Using Correct Username And Password, thì bản chất Test Case này nên thuộc cùng lúc 2 hoạt động kiểm thử, một là Smoke Test vì tính năng đăng nhập là một trong những tính năng chính, hai là chính Suite liên quan đến tính năng đăng nhập, bao gồm đầy đủ những ...Unsuccessfully... và ...Invalid... để kiểm tra hết các trường hợp có thể xảy ra khi một người dùng đăng nhập. Vậy thì có lựa chọn nào cho tester?
Đáp án bạn đang nghĩ đến là: Tạo 1 file test suite mới cho Smoke Test và gọi Resource từ file chứa Test Case, sau đó gọi lại Test Case đấy ở file mới?
Sai, cách này không khả thi, lý do như đã nêu ở bài Library, Resource and Variables. Đầu tiên, một Test Case không thể gọi lại ở file khác như một Keyword.
Vậy thì viết nó thành một keyword thôi được không? Vấn đề là cũng không thể sử dụng một file suite chứa Test Case như một Resource cho file suite khác, mặc dù nó có thể chạy nhưng không đúng thiết kế theo framework.
Vậy thì cách giải quyết khắc phục vấn đề này chính là:
- Sử dụng Resource của Test Suite Login gốc, và phải viết lại Test Case ở file robot mới, cái này làm tăng redundancy của code, tức là có những code đang lặp lại
- Hoặc viết nguyên một keyword hoạt động giống như test case đó rồi dùng như Library. Cái này thì lại thiếu khoa học lý do vì nó vốn đi ngược lại thiết kế
Keyword -> Test Case. Ví dụ
*** Test Cases ***
User Successfully Login Using Correct Username And Password
[Documentation] User successfully login using correct username and password
Open Browser ${URL} ${BROWSER}
Input Text ${USERNAME} ${CORRECT_USERNAME}
Input Text ${PASSWORD} ${CORRECT_PASSWORD}
Click Button ${LOGIN_BUTTON}
Wait Until Page Contains Element ${WELCOME_MESSAGE}
Close Browser
Thay vào đấy là cái củ chuối này
*** Keywords ***
User Successfully Login Using Correct Username And Password
[Documentation] User successfully login using correct username and password
Open Browser ${URL} ${BROWSER}
Input Text ${USERNAME} ${CORRECT_USERNAME}
Input Text ${PASSWORD} ${CORRECT_PASSWORD}
Click Button ${LOGIN_BUTTON}
Wait Until Page Contains Element ${WELCOME_MESSAGE}
Close Browser
*** Test Cases ***
User Successfully Login Using Correct Username And Password
User Successfully Login Using Correct Username And Password
Huh? Alo, what đờ fack is this? Vi phạm tiêu chuẩn viết test case ở mọi framework chứ không chỉ là Robot Framework.
Chính vì thế, Robot Framework cho phép chúng ta thực hiện một số cấu hình để chạy Test Case theo ý muốn của mình.
Test Execution sử dụng command line
Về cơ bản thì mọi khâu vận hành test case đều bắt đầu từ command lines. Việc bạn sử dụng GUI vủa VSCode để chạy test case thì chỉ đơn giản là nó tự tạo lệnh command lines rồi chạy trong terminal của VSCode thôi.
Lệnh chạy test case đơn giản nhất của Robot Framework là:
robot <đường_dẫn_file_robot_chứa_testcase>

Command Lines khi chạy Test Case dùng GUI
Và Robot Framework cung cấp các lựa chọn cấu hình cho dòng lệnh command lines. Cụ thể các bạn có thể đọc ở đây, và đây
Select Modes
Bắt đầu với Select Modes, đây là các cấu hình cho phép chọn các test case, test suite nào chạy, cái nào không được chạy
Select By Test Case
robot --test ...
Về cơ bản thì --test sẽ cho chạy một test case cụ thể theo tên của nó, rất hiếm khi sử dụng trừ khi chúng ta đang viết dở, chạy thử hoặc debug một đoạn mã test case.
robot --test "Test 1" 02__test.robot
Ngoài việc gọi thẳng tên test case được viết ở trong một suite, thì chúng ta cũng có thể áp dụng pattern matching, không nhất thiết phải gọi đúng tên test case đó
robot --test "Test*" 02__test.robot
Ở đây thì bất kỳ test case nào bắt đầu bằng Test đều sẽ được chạy, ngoài ra thì có một số kiểu bắt matching khác mình sẽ viết ở dưới
* là để match với bất kỳ chuỗi nào
? là để match với bất kỳ ký tự nào
[abc] là để match với bất kỳ ký tự nào trong dãy abc
[!abc] là để match với bất kỳ ký tự nào không nằm trong dãy abc
[a-z] là để match với bất kỳ ký tự nào trong dãy từ a đến z
[!a-z] là để match với bất kỳ ký tự nào không nằm trong dãy từ a đến z
Select By Test Suite
robot --suite ...
--suite sẽ cho chạy một test suite cụ thể theo tên của nó, khá thường xuyên sử dụng. Một điều đáng lưu ý là khi này file suite nên có một cái tên. Bởi lẽ, việc chạy nguyên 1 test suite không khác gì chạy một file robot, vậy thì chỉ cần gọi bằng đường dẫn là đủ
robot 01__test_suite.robot
Mắc mớ gì phải gọi tên test suite. Để ứng dụng được cái này, chúng ta sẽ sử dụng trong tình huống sau, giả sử có 2 test suite liên quan đến nhau và ta muốn chạy cùng lúc. Một Suite là suite Login, một suite là Logout, vậy ta làm như sau:
Đầu tiên, đặt tên cho suite dùng Name ở section Settings của file suite
*** Settings ***
Name Login
và
*** Settings ***
Name Logout
Sau đó, gọi chúng trong command lines với pattern matching
robot --suite "Log*" ./
Với cmd line này, tất cả các suite có tên bắt đầu bằng Log ở trong đường dẫn tương đối của cùng working directory sẽ được chạy.
Đồng thời có thể sử dụng --suite cùng với --test để chỉ định một test case thuộc test suite nào, nó sẽ tương tự như --test, chỉ là nó sẽ cho phép bắt nhiều test case thuộc nhiều suite khác nhau nếu dùng pattern matching
robot --suite "Log*" --test "Test*" ./
Lệnh cmd line sẽ cho phép chạy tất cả các test case bắt đầu bằng Test thuộc tất cả các suite bắt đầu bằng Log, nó sẽ mạnh hơn là gọi --test với thẳng tên file, vì như thế chỉ chạy được test case của một file suite
Include And Exclude By Tags
Một lựa chọn khác cho việc chọn test case hoặc bỏ test case thì không thể không kể đến 2 thằng là --include và --exclude. Cả 2 đều dùng để chọn test case theo tags, --include sẽ chọn test case có tag được chỉ định, còn --exclude sẽ loại bỏ test case có tag được chỉ định.
Giả sử với 1 test case sau:
*** Test Cases ***
User Successfully Login Using Correct Username And Password
[Documentation] User successfully login using correct username and password
[Tags] Smoke Login
Open Browser ${URL} ${BROWSER}
Input Text ${USERNAME} ${CORRECT_USERNAME}
Input Text ${PASSWORD} ${CORRECT_PASSWORD}
Click Button ${LOGIN_BUTTON}
Wait Until Page Contains Element ${WELCOME_MESSAGE}
Close Browser
Tag ở đây đang là Smoke và Login, nếu chúng ta cũng có rất nhiều test case khác cũng có tag là Smoke, nhưng chúng nó nằm ở các bộ Suite - file robot khác nhau thì chức năng include luôn là cái cần hướng tới đầu tiên.
robot --include Smoke ./
Lệnh cmd line này sẽ chạy toàn bộ các test case có tag là Smoke ở trong working directory.
Đồng thời, giả sử như chúng ta muốn chạy toàn bộ test case ngoại trừ test case có tag là Smoke, thì chúng ta sẽ sử dụng --exclude
robot --exclude Smoke ./
Hai cấu hình cũng có thể đi với nhau, giả sử khi chúng ta muốn chạy toàn bộ test case có tag là Smoke nhưng muốn bỏ qua test case có tag là Login, thì chúng ta sẽ làm như sau
robot --include Smoke --exclude Login ./
Đồng thời ngoại trừ các cú pháp pattern matching nêu ở trên đây, chúng ta có thể bắt tag theo logic, ví dụ, chúng ta muốn chạy test case có tag Smoke và Login, nếu sử dụng
robot --include Smoke --include Login ./
Thì đây có nghĩa là chúng ta đang chạy các test case có tag Smoke HOẶC Login, còn nếu muốn chạy test case có tag Smoke VÀ Login, thì chúng ta sẽ sử dụng
robot --include SmokeANDLogin ./
Operator logic AND, OR và NOT sẽ giúp chúng ta chọn test case theo ý muốn của mình
AND là để chọn test case có tất cả các tag
OR là để chọn test case có ít nhất một tag trong số đã nêu
NOT là để chọn test case không có tag đã nêu
Order Modes
Với Order Modes, về cơ bản thì đây là cách vận hành test case theo thứ tự. Đôi lúc thì chúng ta sẽ muốn thực hiện các test suite và test case không theo thứ tự từ trên xuống. Khi đấy cần có cấu hình và phương pháp để áp dụng thứ tự chạy test.
Normal Mode
Như đã nêu ở trên, chế độ thường thì không có gì đặc biệt, nó sẽ chạy theo thứ tự từ trên xuống theo thứ tự đặt tên folder và file nếu để tự nhiên như vậy.
Bình thường khi chạy test suite bất kể từ GUI hay cmd lines thì thứ tự luôn là từ trên xuống.
- Với Test Suite, tức là từng file robot, thì thứ tự là thứ tự file robot trong directory, tức là theo thú tự
số -> chữ, số thì theo0-9, còn chữ thì theo alphabeta-z.
Test Suite
├── 01__test_suite.robot
├── 02__test_suite.robot
├── 03__test_suite.robot
├── a__test_suite.robot
Nếu các test suite được phân theo folder thì thứ tự này cũng được áp dụng với folder, các test suite sẽ được chạy theo thứ tự folder trước, rồi ở trong folder sẽ chạy theo thứ tự tên file.
01_TestSuite
├── 01__test_suite.robot
├── 02__test_suite.robot
02_TestSuite
├── 03__test_suite.robot
├── 04__test_suite.robot
Vậy nên trick lỏ mà dân auto test dùng RB hay dùng là đặt tên suite có số ở đầu, tuy nhiên thì vì là trick lỏ nên nó sẽ phát sinh vấn đề khi vào các dòng dự án mà khách hàng yêu cầu test suite phải có tên theo chuẩn của họ.
Còn đối với test case thì ở trong một file robot, thứ tự sẽ luôn là chạy từ trên xuống, nếu muốn thay đổi thứ tự này thì hoặc, là đảo thứ tự test case trong file. Hoặc, có thể chuẩn bị một lệnh cmd lines siêu dài dạng như
robot -t Suite_1.Test_Case_3 -t Suite_2.Test_Case_2 -t Suite_1.Test_Case_2 -t Suite_3.Test_Case_3 ./Tests
Với việc thay đổi thứ tự mà không cần thay đổi cấu trúc file robot thì đây là phương án vẹn toàn nhất, thường thì tester sẽ tạo các câu lệnh chạy rồi lưu nó ở đâu đấy.
Trong cùng 1 file robot thì lệnh sẽ nhìn thế này
robot --test "Test 1" --test "Test 2" --test "Test 3" --test "Test 4" --test "Test 5" <path_or_file>
Nếu các test case thuộc về các file suite khác nhau và với path là ./ - working directory, thì các test sẽ chạy từ directory cao xuống thấp.
Chúng ta sẽ chỉ áp dụng việc thực hiện test case với thứ tự khác trong tình huống các test case độc lập với nhau. Nếu xuất hiện các test case vận hành theo thứ tự của một flow cụ thể thì thường sẽ không ai muốn chạy chúng nó với thứ tự thay đổi
Trong tình huống chúng ta gọi test case theo tag dùng --include hoặc --exclude, thì thứ tự chạy test case nếu không làm rõ sẽ chạy tương tự, theo thứ tự folder cao -> folder thấp, rồi file 0-9 -> file a-z, và cuối cùng là test case thì từ trên xuống.
Nếu thứ tự chạy Smoke cần cụ thể thì tốt nhất là chúng ta nên viết các Test Case này vào một file argument rồi gọi nó trong lệnh cmd lines
Ví dụ, file argument.txt thế này
-s Suite_1 -t Test_1
-s Suite_2 -t Test_2
-s Suite_1 -t Test_2
Khi gọi nó trong cmd lines
robot --argumentfile argument.txt <path_or_file>
Thường thì nên để file argument ở trong cùng một folder với directory tổng chạy test, nhưng cũng có thể đặt nó vào một folder khác, nhưng khi đó cần phải chỉ định đường dẫn đến file argument như cách chỉ định đường dẫn để chạy test nhưng phải cụ thể tới tận file argument.
Parallel Mode
Chế độ song song nôm na là chạy nhiều test cùng lúc. Robot Framework core chạy tuần tự; muốn chia suite hoặc test ra nhiều process thì dùng runner ngoài là Pabot.
Đầu tiên cần cài đặt
pip install -U robotframework-pabot
Sau đó, chạy test case bằng pabot thay vì robot
pabot <path_or_file>
Với lệnh chạy cơ bản thì các test suite sẽ được chạy song song, ngoài ra, nếu muốn chạy test case song song thì cần đưa argument --testlevelsplit vào lệnh cmd lines
pabot --testlevelsplit <path_or_file>
Chạy song song ăn CPU, RAM, browser session và cả test data. Đừng phụ thuộc vào default của từng phiên bản Pabot; muốn CI dễ đoán thì đặt rõ số worker bằng --processes.
pabot --processes 4 <path_or_file>
--processes 4 nghĩa là cho phép tối đa bốn executor chạy song song, không phải ép bốn process vào một CPU core. Con số hợp lý phải đo trên chính runner và còn phụ thuộc test có mở browser, dùng chung account hay tranh cùng một database hay không.
Ví dụ
#tests/SuiteA.robot
*** Test Cases ***
Test Case 1
Log Test Case 1
Sleep 10s
Test Case 2
Log Test Case 2
Sleep 10s
Test Case 3
Log Test Case 3
Sleep 10s
#tests/SuiteB.robot
*** Test Cases ***
Test Case A
Log Test Case A
Sleep 10s
Test Case B
Log Test Case B
Sleep 10s
Test Case C
Log Test Case D
Sleep 10s
Đầu tiên, lệnh pabot tests sẽ cho chạy Suite A và Suite B song song, trong đó các test case vẫn chạy tuần tự từ trên xuống.
pabot --testlevelsplit tests
Lệnh này sẽ chạy cả Suite A và Suite B song song, đồng thời là cả các test case trong Suite A và Suite B cũng chạy song song.
Nếu sử dụng Test Suite Setup và Test Suite Teardown thì cần chú ý, vì nó sẽ chạy trên mỗi lần xuất hiện của Test Suite. Tức là với pabot tests thì sẽ có 2 lần Suite Setup/Teardown, còn với pabot --testlevelsplit tests thì sẽ có 6 lần Suite Setup/Teardown do 6 test case được chạy độc lập trên 6 process.
Ngoài ra, nếu có Test Setup và Test Teardown thì nó sẽ chạy trên mỗi lần xuất hiện của Test Case như bình thường
Random Mode
Như đúng cái tên, nó sẽ chạy loạn lên không theo thứ tự với các test suite và test case. Lệnh cmd lines sẽ như sau
robot --randomize <what_to_random> <path_or_file>
Với <what_to_random> là tests, suites, all, none
testssẽ chạy test case theo thứ tự ngẫu nhiênsuitessẽ chạy test suite theo thứ tự ngẫu nhiên, nhưng test case ở trong suite vẫn chạy theo thứ tựallsẽ chạy cả test suite và test case theo thứ tự ngẫu nhiênnonesẽ chạy theo thứ tự mặc định
Ví dụ
robot --randomize tests ./tests
Properties Modes
dryrun
Dry Run - chạy khô thì hiểu đơn giản là nó sẽ cho chạy test suite và test case nhưng không thật sự chạy keyword. Tức là giả sử có một keyword Open Browser lấy từ SeleniumLibrary thì nó chỉ chạy qua cái keyword đấy mà không làm gì.
Mục đích của Dry Run sinh ra là để xác minh, hoặc là syntax, xem các keyword có được gọi đúng không, xác minh sử dụng biến và xác minh test data.
Ưu điểm của việc dùng Dry Run để debug test case là vì nó không thật sự chạy keyword, nên tốc độ rất nhanh. Trong tình huống bình thường, giả sử bạn sử dụng sai một biến, kiểu như sau
*** Variables ***
@{BROWSER} Chrome Firefox Edge
# ...
*** Test Cases ***
User Successfully Login Using Correct Username And Password
[Documentation] User successfully login using correct username and password
Open Browser ${URL} @{BROWSER}[1]
# ...
Chạy Test Case này lỗi là cái chắc, và nó sẽ chạy bình thường cho đến khi gặp keyword dùng sai cách gọi biến, đúng ra phải dùng ${BROWSER}[1] thay vì @{BROWSER}[1]. Nếu sử dụng Dry Run thì nó sẽ lướt qua các keyword rất nhanh và ngay lập tức báo fail test case và trả ra lỗi.
robot --dryrun ./tests
Rerun Failed
Khi bước vào các dòng dự án có rất nhiều test, thì nhiều khi chúng ta sẽ muốn chạy lại các test case hay test suite đã fail. Ví dụ như các retest chẳng hạn, thì xét về logic mà nói, nếu có chỉ một hai test case hay suite cần chạy lại thì còn đỡ, nhưng cùng một bug đấy lại khiến ti tỉ case và suite cùng fail thì việc theo dõi các case nào fail và chạy lại sẽ khiến đầu chúng ta bạc thêm chút.
RB cho ra một file gọi là output.xml, chúng ta có thể dựa vào file này để chạy lại các test case hay test suite đã fail. File output này sẽ được trả ra mỗi lần chúng ta chạy test.
Quy trình mình hay áp dụng như sau:
- Chạy test case, nếu có test case fail, xác định nó fail vì bug hay lỗi test (flaky, thiếu ổn định,...)
- Lưu lại file
output.xml - Chuyển bug cho dev, sau khi dev sửa lỗi, chúng ta sẽ chạy lại test case đã fail
Nếu chúng ta muốn chạy lại các case đã fail, thì sử dụng
robot --rerunfailed output.xml
Nếu muốn chạy lại cả Suite
robot --rerunfailedsuites output.xml
Lưu ý là việc rerun theo case đòi hỏi test case phải được viết rất hoàn chỉnh, đảm bảo chúng có thể vận hành độc lập khỏi suite, nếu không thì ưu tiên rerun theo suite.
Cũng áp dụng cho các hành động chạy test với cấu hình, --include, --exclude, --test, --suite, --randomize, --dryrun, --rerunfailed, --rerunfailedsuites đều có thể kết hợp được
Đặc biệt hữu dụng khi chạy --include theo tag Smoke, khi lỗi thì sau khi fix được vấn đề, làm nhát --rerunfailed để chạy lại các test case Smoke đã fail
Test Execution sử dụng Tags
Select Tags
--include và --exclude là cách chúng ta chọn test case theo tag như mình đã nêu ở trên rồi
Ngoài ra còn có --skip và --skiponfailure để chọn test case theo tag, nhưng chúng ta sẽ bỏ qua test case có tag được chỉ định.
Với --skip thì nó sẽ bỏ qua các test case hay suite có tag chỉ định, ví dụ như nếu chúng ta có một nhóm các test case hay suite chưa viết xong, chúng ta sẽ đấm tag unfinished vào đó, và khi chạy test case, chúng ta sẽ bỏ qua chúng
robot --skip unfinished <path_or_file>
Với --skiponfailure thì nó sẽ bỏ qua các test case hay suite có tag chỉ định nếu chúng fail và sẽ không được tính vào kết quả cuối cùng. Hữu dụng trong tình huống chúng ta xác định được trước cái gì sẽ fail, hay biết trước khả năng một số test case bị flaky
robot --skiponfailure flaky <path_or_file>

Log khi một test case bị skip
robot: Tags
Một điểm nữa mà mình muốn đề cập là RB cung cấp cấu hình cho test case hay suite ngay từ khâu viết test bằng cách sử dụng tag robot:, một số tính năng cũng sẽ mới mẻ và chưa được đề cập ở trên như Continue On Failure, tức là chạy tiếp test case khi có một keyword fail.
robot
và robot | Kích hoạt continue-on-failure mode cho test case hay suite. robot và robot | Bỏ continue-on-failure mode. Trong tình huống nó được đặt cho suite và giờ chúng ta muốn gỡ cho test case lẻ robot | Đánh test có thể bỏ qua nếu fails. robot | Đánh test để skip qua vô điều kiện. robot | Đánh test để bị exclude vô điều kiện. robot | Đánh test không dryrun trong tình huống gọi dryrun tổng thể, ví dụ như gọi dryrun cả suite nhưng chúng ta muốn test case này chạy thật. robot | Tự động dừng test và đánh fail từ test case hay keyword này trở đi.Ví dụ
*** Test Cases ***
Test Case 1
[Tags] robot:skip
Log Test Case 1