Mình sẽ nói nhanh một chút về áp dụng Data Driven Testing trong Robot Framework. Vấn đề chính của áp dụng DDT là nhét data vào kiểu gì, thì RB có một Library tên DataDriver hỗ trợ input data từ file Excel (XLSX) và CSV, chuẩn cũ XLS cũng hỗ trợ nhưng mà thôi, 2024 rồi thì quên nó đi.
Cũng tồn tại một cách đưa data vào tốc độ cao hơn là dùng JSON, mình cũng sẽ nói trong bài này.
Truyền thống
Phương pháp truyền thống để áp dụng Data Driven và cũng là cổ lỗ sĩ nhất chính là dùng thẳng section Test Case, phương pháp này là default của Robot Framework.
*** Settings ***
Test Template Login with invalid credentials should fail
*** Test Cases *** USERNAME PASSWORD
Invalid User Name invalid ${VALID PASSWORD}
Invalid Password ${VALID USER} invalid
Invalid User Name and Password invalid invalid
Empty User Name ${EMPTY} ${VALID PASSWORD}
Empty Password ${VALID USER} ${EMPTY}
Empty User Name and Password ${EMPTY} ${EMPTY}
*** Keywords ***
Login with invalid credentials should fail
[Arguments] ${username} ${password}
Log Many ${username} ${password}
Mục Test Cases sẽ được viết bổ sung các cột argument để truyền vào test template. Tên của các Test Cases sẽ được vẫn giữ nguyên nhưng nội dung của các Test Cases sẽ đều giống nhau và chạy chỉ keyword Login with invalid credentials should fail. Phần Logic của các Test Case được giấu đi bằng việc sử dụng Test Template trên Settings.
Để có thể hoàn toàn chạy ví dụ mình đưa ở trên thì bạn cần truyền thêm giá trị cho các biến ${VALID PASSWORD}, ${VALID USER} và ${EMPTY} trên section Variables, nếu bạn muốn thử
*** Variables ***
${VALID USER} name
${VALID PASSWORD} 123
${EMPTY}
Ưu điểm của cách làm này là dễ hiểu, dễ sử dụng, nhưng rất yếu khi phải thực hiện test với rất nhiều bộ test data, vài trăm vài nghìn records thì không thể chơi kiểu này.
Đây cũng là một cách để test cách sử dụng data trước khi triển kai DataDriver hay JSON nhưng cũng có thể sử dụng --dryrun để check import Data, nên về cơ bản mình khong khuyến khích sử dụng cách này ở bất kỳ thời điểm nào trong giai đoạn viết Test Case.
DataDriver
Vượt trội hơn phương pháp truyền thống là sử dụng DataDriver, nó cho phép sử dụng test data được viết trong các file XLSX và CSV.
Đầu tiên bạn cần cài đặt Library này do nó bản chất là một External Library
pip install robotframework-datadriver
Cách sử dụng thì không có gì đáng nói, vẫn sử dụng Test Template trên section Settings nhưng cũng hơi khác vì chúng ta sẽ phải tổ chức file data theo xlsx và csv.
Cụ thể, file robot vẫn viết
*** Settings ***
Library DataDriver <đường dẫn file csv>
Test Template Login With User And Password
*** Test Cases ***
Login With User And Password ${username} ${password}
*** Keywords ***
Login With User And Password
[Arguments] ${username} ${password}
Log Many ${username} ${password}
Đầu tiên, nếu bạn không cần quan tâm đến tên của Test Case trong report thì cứ đặt tên Test Case theo keyword.
Tiếp theo, chúng ta cần tạo Test Data, bắt đầu với CSV
CSV File
Bạn hoàn toàn có thể soạn file CSV bằng Excel rồi Save as CSV, nó nhanh hơn là ngồi gõ tay trên text editor, vừa dễ nhầm và sai syntax, nhìn còn loạn, tội gì?
Đầu tiên, cần đủ số cột như sau:
- Cột đầu là
***Test Cases*** - Cột thứ hai là
${username}, phải đưa đủ vào dấu${}để DataDriver hiểu được đây là biến, nếu chỉ truyền vàousernamethì No No - Cột thứ ba là
${password}

Viết file CSV trong Excel, tên test.csv
Về nội dung của từng dòng, lần lượt sẽ đi theo đúng nội dung của cột từ trái qua phải.
*** Test Cases ***là tên Test Case, có thể để trống, nếu để trống thì nó sẽ lấy tên theo tên gốc của keyword${username}là giá trị của biếnusername, có thể điền bất cứ cái gì như số hay chữ${password}là giá trị của biếnpassword, cũng có thể điền bất cứ cái gì như số hay chữ
Khi các giá trị được đưa vào RB, dù sao nó cũng sẽ tự động được ép kiểu, vì ${username} và ${password} đều sẽ được xử lý như String, nên kể cả nếu đưa giá trị số cho ${password} thì nó vẫn sẽ được xử lý như String.
Đầu tiên, một đièu mà bạn sẽ gặp phải chính là khi chạy test case này
*** Settings ***
Library DataDriver ./test.csv
Test Template Login With User And Password
*** Test Cases ***
Login With User And Password ${username} ${password}
*** Keywords ***
Login With User And Password
[Arguments] ${username} ${password}
Log Many ${username} ${password}
Mặc dù file csv được tạo đúng, format cũng đúng, nhưng lỗi. Vì nếu để ý, bạn sẽ thấy DataDriver thật ra nhận vào tham số, vì nó có tham số

Các tham số của DataDriver
Nếu mở file test.csv trên text editor, bạn sẽ thấy dạng text của nó , nó sử dụng dấu phẩy (,) để tách các phần từ như tên cột, các trường, và dùng break để xuống dòng
***Test Cases***,${username},${password}
Right user empty pass,name,
Right user wrong pass,name,123
,name,right
Còn ở trong function DataDriver, tham số delimiter lại được default là dấu chấm phẩy (;). Vậy nên, bạn cần phải thêm tham số delimiter=',' vào sau tên file csv, đồng thời khi truyền tham số thì bạn cần phải cung cấp cả dialect=UserDefined và tên tham số của file=
*** Settings ***
Library DataDriver file=./test.csv dialect=UserDefined delimiter=,
Test Template Login With User And Password
*** Test Cases ***
Login With User And Password ${username} ${password}
*** Keywords ***
Login With User And Password
[Arguments] ${username} ${password}
Log Many ${username} ${password}

Log
Như vậy với test case có data không được truyền vào ***Test Cases*** thì nó sẽ lấy tên đặt sẵn ở section Test Cases.
Mình khuyến khích cách setup như mình, bởi lẽ tạo file csv bằng excel là nhanh nhất, còn không nếu muốn sử dụng kiểu gọi default
*** Settings ***
Library DataDriver ./test.csv
Thì cần phải soạn tay file CSV, hoặc nhanh hơn là vào text editor và thay thế mọi dấu , thành ;

Tính năng text replace của VSCode
XLSX File
Bây giờ mình đã lưu file csv vừa rồi ở dạng XLSX, cách sử dụng thì còn dễ hơn do không phải quá lo lắng về việc format file, vì XLSX là XLSX, không có nhưng.
*** Settings ***
Library DataDriver file=./test.xlsx
Test Template Login With User And Password
*** Test Cases ***
Login With User And Password ${username} ${password}
*** Keywords ***
Login With User And Password
[Arguments] ${username} ${password}
Log Many ${username} ${password}
Lưu ý có thể bổ sung sheet_name để xác định sheet sử dụng làm test data, nếu không thì DataDriver sẽ lấy sheet đầu tiên làm test data.
*** Settings ***
Library DataDriver file=./test.xlsx sheet_name=Sheet1
Test Case sẽ chạy mà không có vấn đề gì, nhưng một cái bạn sẽ để ý đấy là khởi động Test Case sẽ mất thời gian, càng nhiều data lấy ra càng lâu nên mình không khuyến khích sử dụng XLSX, nếu có file XLSX thì hãy lưu ở dạng CSV trước rồi làm như trên mình ví dụ.
JSON
Cách sử dụng JSON thì lại không sử dụng DataDriver, nhưng nó rất nhanh do Python xử lý file JSON nhan hơn là CSV và XLSX. Để ứng dụng được Data Driven với JSON thì chúng ta cần sử dụng
- JSON Library để đọc file JSON
- Một Library tự viết - file python để lấy data từ JSON dùng cho các test
Đầu tiên, cài đặt JSON Library
pip install robotframework-jsonlibrary
Tiếp theo, một file robot dùng JSON sẽ trông như sau
*** Settings ***
Library JSONLibrary
Library robot.utils
Suite Setup Load Variable Data
Test Template Login With User And Password
*** Keywords ***
Load Variable Data
${ABS_PATH} = Abspath test_data/test_data.json
${DATA} Load Json From File ${ABS_PATH}
Set Suite Variable ${USERNAME} ${DATA}[username]
Set Suite Variable ${PASSWORD} ${DATA}[password]
Login With User And Password
[Arguments] ${username} ${password}
Log Many ${username} ${password}
*** Test Cases ***
Login With User And Password ${username} ${password}
Với test_data/test_data.json là đường dẫn tới file JSON tính từ Current Working Directory. Tức là nếu terminal của bạn hiện là
PS C:\Users\Duy Van\Downloads\Duy247.github.io>
Thì đường dẫn sẽ tính từ đây đi vào file json. Và file json mình viết như sau, tạm thời chỉ với một record
{
"username": "name",
"password": "123"
}
Để giải thích cho nội dung của file suite mình ví dụ:
- Đầu tiên, sẽ có 2 Library cần import, một là JSONLibrary, một là robot.utils, thằng robot utils sẽ giải thích sau. Nhưng JSONLibrary sẽ cung cấp khả năng đọc file JSON, bạn có thể đọc thêm ở đây
- Test Template vẫn sẽ tương tự khi triển khai DataDriver
- Suite Setup: Chúng ta sẽ cần kéo data ra khỏi file JSON và gán nó vào biến, không có cách nào để triển khai nó dùng Setting nên phải triển khai nó dùng keyword, và chúng ta phải gọi nó ra ở đầu test nên mình để nó là Suite Setup
Thật ra có cách để triển khai file JSON giống DataDriver, nhưng chúng ta sẽ phải viết một Library riêng phức tạp, nên cái đấy thì mình sẽ nghiên cứu
- Keyword sử dụng làm Suite Setup dùng keyword của library JSON
Load Json From File, keyword lấy vào đường dẫn tuyệt đối của file json, vì thế mình cần library thứ hai là robot.utils để lấy đường dẫn tuyệt đối của file json - Sau đó mình gán giá trị của
usernamevàpasswordvào biến${USERNAME}và${PASSWORD}của Suite

Log sử dụng JSON
Thật ra có một cách nhanh hơn
Vì cách trên của mình chính là một pha OVTK giai đoạn cuối khi mình ngồi suy nghĩ cách sử dụng JSON, bản chất Robot Framework hỗ trợ argument --variablefile khi sử dụng command line để chạy test, khi đấy file Suite sẽ chỉ thế này
*** Settings ***
Test Template Login With User And Password
*** Keywords ***
Login With User And Password
[Arguments] ${username} ${password}
Log Many ${username} ${password}
*** Test Cases ***
Login With User And Password ${username} ${password}
Sau đó, gọi cmd lines
robot --variablefile test_data/test_data.json test.robot
Vậy là xong

Log sử dụng JSON từ cmd line
Tuy nhiên mình không khuyến khích cách này vì nó không thể sử dụng một bộ JSON lớn.
Nếu sử dụng như cách thứ nhất và áp dụng Loop để chạy nhiều bộ data trong file JSON thì dù sao nó cũng tính vào trong một keyword chứ không tính thành các test case riêng biệt
Có một phương pháp cuối cùng mình nghiên cứu cho phép lấy data từ JSON và chạy nhiều test case, cụ thể:
- Sẽ tồn tại 1 thư mục chứa rất nhiều file JSON
- Mỗi file JSON tương ứng 1 test case và chứa bộ data riêng
Sau đấy viết file robot như sau:
*** Settings ***
Library DataDriver file=${CURDIR}/DataFiles/*_test.json reader_class=glob_reader
Library OperatingSystem
Test Template Test All Files
*** Test Cases ***
Glob_Reader_Test 1_test
*** Keywords ***
Test All Files
[Arguments] ${file_name}
${file_content}= Get File ${file_name}
${username}= Evaluate json.loads($file_content)["username"]
${password}= Evaluate json.loads($file_content)["password"]
Log Many ${username} ${password}
Mục tiêu của file Robot chính là:
- Đầu tiên, đọc toàn bộ các file đuôi
test.jsontừ thư mụcDataFiles - Lấy File Name của từng file JSON và truyền vào keyword đang được dùng làm Test Template
- Keyword Test All Files lấy vào argument là file json, sau đó sẽ lấy nội dung của file JSON, sau đó lấy giá trị của
usernamevàpasswordtừ file JSON, cuối cùng log ra
Combo này sẽ mô phỏng chính xác quá trình lấy data từ file JSON ra. Log của nó cũng sẽ tách từng file thành từng test case riêng, đi rất sát với mô hình Data Driven thật sự

Log sử dụng JSON lẻ
Kết
Với bài viết này, có lẽ là bạn đã nắm được cách ứng dụng Data Driven trong Robot Framework rồi, sử dụng CSV, XLSX hay JSON. Tuy nhiên với JSON thì phương pháp ứng dụng vẫn chưa được hoàn thiện nên mình sẽ nhấn mạnh và bỏ ngỏ nó ở cuối bài.