Hầu hết bài kiểm tra API chạy tuyến tính: gọi đăng nhập, gọi thanh toán, gọi biên nhận rồi xác nhận kết quả. Cách này trở nên không hiệu quả khi một bước thất bại khiến bước sau không còn ý nghĩa. Ví dụ, nếu đăng nhập trả về 401, việc tiếp tục gọi API thanh toán chỉ tạo thêm lỗi nhiễu và che khuất nguyên nhân gốc. Bạn cần một kịch bản đọc phản hồi đăng nhập, quyết định có tiếp tục hay không, rồi báo cáo chính xác điểm thất bại.
Đó là bài toán kiểm soát luồng. Trong bài này, bạn sẽ thêm nhánh if/else vào kịch bản kiểm tra API trong Apidog: chỉ gọi API thanh toán khi đăng nhập thành công. Nếu bạn chưa quen với Test Scenario, hãy xem hướng dẫn cách viết kịch bản kiểm tra với Apidog. Để nắm nền tảng về điều kiện, hướng dẫn câu lệnh điều kiện của MDN là tài liệu phù hợp.
Kiểm soát luồng là gì?
Trong Apidog, bài kiểm tra tự động nằm trong mô-đun Tests. Đơn vị làm việc là Test Scenario, tương tự Collection trong Postman.
Một kịch bản gồm nhiều Test Steps. Mỗi bước có thể là:
- Một yêu cầu API.
- Một phần tử kiểm soát luồng, như nhánh điều kiện, vòng lặp hoặc độ trễ.
Kiểm soát luồng cho phép kịch bản xử lý nhiều hơn một chuỗi request cố định. Theo tài liệu Apidog về kiểm soát luồng và phân nhánh điều kiện, bạn có thể dùng các phần tử như:
-
Conditional Branching: nhánh
if/else. - For Loop và ForEach Loop: lặp qua số lần hoặc mảng dữ liệu.
- Wait: chờ giữa các bước.
- Break If và On Error: kiểm soát vòng lặp và lỗi.
Phân nhánh không phải vòng lặp.
Nhánh quyết định một lần liệu một nhóm bước có chạy hay không. Vòng lặp chạy lại cùng một nhóm bước nhiều lần.
Nếu cần gọi API với từng ID đơn hàng trong một mảng, hãy dùng ForEach thay vì Conditional Branching. Xem thêm hướng dẫn vòng lặp ForEach.
Tài liệu Apidog không nêu giới hạn gói tính năng riêng cho kiểm soát luồng, phân nhánh điều kiện, vòng lặp hoặc truyền dữ liệu giữa bước. Không có phân biệt được ghi nhận giữa bản cloud và self-hosted cho các tính năng này.
Xây dựng kịch bản: chỉ thanh toán khi đăng nhập thành công
Mục tiêu của kịch bản:
- Gọi API đăng nhập.
- Kiểm tra mã trạng thái phản hồi.
- Nếu mã là
200, gọi API thanh toán. - Nếu mã khác
200, báo lỗi rõ ràng và không chạy thanh toán.
Bước 1: Tạo Test Scenario
Trong Apidog:
- Mở mô-đun Tests.
- Nhấp dấu
+cạnh thanh tìm kiếm. - Chọn Test Scenario mới.
- Chọn thư mục lưu trữ và thiết lập mức ưu tiên.
- Tạo kịch bản.
Bạn sẽ có một kịch bản trống để thêm các bước kiểm tra.
Bước 2: Thêm request đăng nhập
Thêm Test Step đầu tiên bằng một trong các cách:
- Chọn endpoint có sẵn từ API specification.
- Chọn endpoint case đã lưu.
- Thêm request tùy chỉnh.
- Nhập từ lệnh cURL.
Để thực hành nhanh, thêm một request tùy chỉnh:
POST https://api.your-store.com/v1/login
Content-Type: application/json
{
"email": "dana@example.com",
"password": "correct-horse-battery-staple"
}
Chạy request một lần để kiểm tra phản hồi. Một lần đăng nhập thành công có thể trả về:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"userId": "usr_10482"
}
Ở bước này, hãy xác nhận:
- Status code là
200. - Body chứa token hoặc dữ liệu bạn cần ở các request sau.
- Endpoint đang dùng đúng môi trường test.
Bước 3: Mở chế độ điều phối
Nhấp vào một bước bất kỳ để vào orchestrate mode.
Giao diện sẽ hiển thị:
- Bảng bên trái: toàn bộ luồng kịch bản.
- Bảng bên phải: cấu hình của bước đang chọn.
Bạn có thể kéo biểu tượng ≡ để thay đổi thứ tự các bước.
Bước 4: Thêm Conditional Branching
Nhấp Add Step và chọn Conditional Branching.
Apidog sẽ tạo một khối If trống. Tiếp theo, cấu hình điều kiện dựa trên phản hồi đăng nhập.
Các toán tử điều kiện có sẵn gồm:
EqualsDoes not equalExistsDoes not existLess thanLess than or equalGreater thanGreater than or equalMatches with RegexContainsDoes not containIs emptyIs not EmptyIn ListNot in List
Với ví dụ này, điều kiện cần đạt là:
login response status Equals 200
Bước 5: Đọc dữ liệu từ bước đăng nhập
Bạn có hai cách để dùng dữ liệu từ request trước trong điều kiện hoặc request tiếp theo.
Cách 1: Retrieve pre-step data
Trong trường giá trị của điều kiện:
- Nhấp biểu tượng đũa thần.
- Chọn Retrieve pre-step data.
- Chọn bước đăng nhập.
- Chọn giá trị trạng thái phản hồi.
Apidog dùng tham chiếu bước trước theo cú pháp:
{{$.<step id>.response.body.<field path>}}
Ví dụ, để lấy token từ body của bước có ID 1:
{{$.1.response.body.token}}
Lưu ý quan trọng:
- Retrieve pre-step data chỉ hoạt động trong mô-đun Tests, không dùng trong mô-đun APIs.
- Giá trị chỉ được resolve khi chạy toàn bộ kịch bản.
- Nếu chạy riêng một step và thấy tham chiếu trống, đó là hành vi bình thường.
Cách 2: Extract Variable
Nếu cần tái sử dụng dữ liệu ở nhiều nơi, hãy trích xuất thành biến.
Trong request đăng nhập:
- Mở phần post-processors.
- Thêm hành động Extract Variable.
- Dùng JSONPath để lấy trường cần thiết, ví dụ:
$.token
- Đặt tên biến, ví dụ
token.
Sau đó tham chiếu biến ở các bước sau:
{{token}}
Cách này phù hợp khi token cần dùng ở nhiều nhánh hoặc cả mô-đun Tests và APIs. Xem thêm cách truyền dữ liệu giữa các bước kiểm tra.
Với điều kiện kiểm tra status code, Retrieve pre-step data là cách ngắn nhất.
Bước 6: Thêm nhánh Else
Di chuột lên khối If và nhấp + Else.
Bây giờ cấu hình hai nhánh:
Nhánh If: gọi API thanh toán
Thêm request thanh toán bên trong khối If.
Request này chỉ chạy khi đăng nhập trả về 200. Nếu API thanh toán cần token, dùng biến đã trích xuất:
POST https://api.your-store.com/v1/checkout
Authorization: Bearer {{token}}
Content-Type: application/json
{
"productId": "prod_123",
"quantity": 1
}
Bạn cũng có thể dùng tham chiếu trực tiếp từ bước đăng nhập thay vì biến. Mẫu bearer token này tương tự các request được xác thực trong tài liệu Stripe API.
Nhánh Else: báo lỗi có chủ đích
Trong khối Else, thêm một bước để lỗi được ghi nhận rõ ràng. Ví dụ:
- Gọi endpoint logging.
- Gọi endpoint notification.
- Thêm request tùy chỉnh kèm assertion luôn thất bại.
Mục tiêu là bảo đảm lần chạy hiển thị lỗi đăng nhập thay vì tiếp tục sang lỗi thanh toán không liên quan.
Luồng cuối cùng sẽ là:
Nếu login.status === 200
→ chạy checkout
Ngược lại
→ báo lỗi và dừng đường dẫn thanh toán
Bước 7: Lưu và chạy toàn bộ kịch bản
Nhấp Save All để lưu.
Nếu có dấu chấm báo thay đổi chưa lưu, hãy lưu trước khi chạy. Sau đó chạy toàn bộ kịch bản:
- Dùng thông tin đăng nhập hợp lệ: nhánh
Ifchạy. - Dùng thông tin đăng nhập không hợp lệ: nhánh
Elsechạy. - Kiểm tra lịch sử chạy để xác nhận checkout không được gọi khi login thất bại.
Các biến thể thực tế
Phân nhánh theo trường trong response body
Không nhất thiết phải kiểm tra status code.
Ví dụ API vẫn trả 200 cho tài khoản bị khóa, nhưng body chứa:
{
"status": "locked"
}
Bạn có thể dùng tham chiếu:
{{$.1.response.body.status}}
Sau đó cấu hình điều kiện:
Equals "active"
Một số ví dụ khác:
- Dùng
Containsđể kiểm tra chuỗi thông báo. - Dùng
Greater thanđể kiểm tra số dư. - Dùng
In Listđể xác nhận vai trò người dùng thuộc tập giá trị được phép.
Kết hợp nhánh với ForEach
Bạn có thể đặt Conditional Branching bên trong một vòng lặp ForEach.
Ví dụ: lặp qua danh sách sản phẩm và chỉ xử lý các sản phẩm còn hàng.
Tham chiếu trong vòng lặp:
{{$.<loop step id>.index}}
Chỉ mục bắt đầu từ 0.
Để truy cập phần tử hiện tại:
{{$.<loop step id>.element.<field path>}}
Ví dụ với từng sản phẩm:
{{$.3.element.productId}}
Xem chi tiết trong hướng dẫn vòng lặp ForEach.
Dừng vòng lặp với Break If
Trong vòng lặp, dùng Break If condition để kết thúc lặp ngay khi điều kiện đạt.
Bạn có thể:
- Kéo phần tử này đến vị trí cần kiểm tra.
- Thêm nhiều Break If trong cùng một vòng lặp.
- Dừng khi tìm thấy bản ghi phù hợp hoặc khi API trả về lỗi cụ thể.
Xử lý lỗi trong vòng lặp với On Error
Phần tử On Error nằm cố định ở đầu vòng lặp. Các tùy chọn gồm:
-
Ignore: bỏ qua lỗi và tiếp tục request tiếp theo. -
Continue: bỏ qua phần còn lại của lần lặp hiện tại. -
Break execution: dừng vòng lặp và tiếp tục sau vòng lặp. -
End execution: dừng toàn bộ kịch bản.
Chọn hành vi dựa trên mức độ nghiêm trọng của lỗi. Ví dụ, dùng Continue cho một bản ghi lỗi không quan trọng, nhưng dùng End execution khi token xác thực hết hạn.
Chờ giữa các bước với Wait
Dùng phần tử Wait khi hệ thống cần thời gian để phản ánh thao tác ghi.
Ví dụ:
POST /orders
→ Wait 1000 ms
→ GET /orders/{id}
Độ trễ được tính bằng mili giây. Đây là lựa chọn hữu ích khi kiểm tra hệ thống bất đồng bộ hoặc eventual consistency.
Dùng dữ liệu trong script
Khi điều kiện phức tạp hơn các toán tử có sẵn, hãy dùng pre-processor hoặc post-processor script.
Trong script, bạn không thể dùng trực tiếp:
{{variable}}
Thay vào đó, dùng:
pm.variables.get("$.2.response.body.token")
Trong đó 2 là ID bước và phần còn lại là đường dẫn đến dữ liệu cần lấy.
Để tìm hiểu thêm về việc dùng output của request trước làm input cho request sau, xem:
Một kịch bản không thể tự tham chiếu chính nó. Cơ chế này giúp tránh vòng lặp vô hạn khi lồng kịch bản.
Chạy kịch bản trong CI với Apidog CLI
Kịch bản không chỉ chạy trong giao diện Apidog. Bạn có thể chạy headless trong CI bằng Apidog CLI.
Cài đặt CLI và đăng nhập:
npm install -g apidog-cli
apidog login --with-token <YOUR_ACCESS_TOKEN>
Chạy Test Scenario theo ID:
apidog run --access-token $APIDOG_ACCESS_TOKEN -t <scenario_id> -e <env_id> -r cli
Ý nghĩa các tham số:
-
-t: ID của Test Scenario. -
-e: ID môi trường. -
-r: reporter.
Các reporter gồm:
-r cli
-r html
-r junit
Bạn có thể xuất nhiều định dạng cùng lúc:
apidog run \
--access-token $APIDOG_ACCESS_TOKEN \
-t <scenario_id> \
-e <env_id> \
-r html,cli
Khi chạy trong CI, nhánh được xử lý giống như trong ứng dụng:
- CLI gọi API đăng nhập.
- Đọc phản hồi.
- Chạy nhánh
IfhoặcElse. - Trả exit code theo kết quả chạy.
Vì vậy, đăng nhập thất bại có thể làm fail build thay vì để pipeline tiếp tục chạy các bước phụ thuộc.
Xem thêm:
- Hướng dẫn cài đặt Apidog CLI
- Hướng dẫn Apidog CLI với GitHub Actions
- Cách lên lịch kiểm tra API trong Apidog
Câu hỏi thường gặp
Phân nhánh Điều kiện khác gì vòng lặp?
Conditional Branching quyết định một lần liệu một khối bước có chạy hay không.
Vòng lặp chạy cùng một khối nhiều lần.
- Dùng nhánh cho quyết định
if/else, ví dụ chỉ checkout khi login thành công. - Dùng For hoặc ForEach khi cần lặp qua số lượng hoặc mảng dữ liệu.
Xem hướng dẫn vòng lặp ForEach để triển khai phần lặp.
Vì sao Retrieve pre-step data trả về trống?
Có hai nguyên nhân phổ biến:
- Tính năng này chỉ hoạt động trong mô-đun Tests, không hoạt động trong APIs.
- Nó chỉ được resolve khi chạy toàn bộ Test Scenario.
Hãy chạy toàn bộ kịch bản thay vì chạy riêng lẻ một bước.
Tôi có thể phân nhánh theo field trong response body không?
Có.
Dùng tham chiếu như:
{{$.1.response.body.status}}
Hoặc trích xuất field thành biến và dùng các toán tử như:
EqualsContainsIn List
Mọi giá trị có thể tham chiếu đều có thể dùng làm điều kiện. Xem cách truyền dữ liệu giữa các bước kiểm tra.
Làm sao dùng biến trong script?
Không dùng trực tiếp cú pháp {{variable}} trong script.
Dùng:
pm.variables.get("$.2.response.body.token")
Áp dụng trong pre-processor hoặc post-processor script, với ID bước và field path tương ứng.
Phân nhánh có yêu cầu gói riêng hoặc self-hosted không?
Tài liệu Apidog không nêu giới hạn gói riêng cho kiểm soát luồng, phân nhánh, vòng lặp hoặc truyền dữ liệu. Cũng không có phân biệt được ghi nhận giữa cloud và self-hosted cho các tính năng này.
Tổng kết
Bài kiểm tra tuyến tính chỉ cho biết một bước nào đó đã hỏng. Bài kiểm tra có phân nhánh cho biết lỗi xảy ra ở đâu và tránh gọi các API phụ thuộc khi điều kiện đầu vào không đạt.
Để triển khai:
- Thêm Conditional Branching.
- Đọc phản hồi bước trước bằng Retrieve pre-step data hoặc biến đã trích xuất.
- Cấu hình điều kiện
If. - Thêm đường dẫn
+ Else. - Chạy toàn bộ kịch bản để kiểm tra cả hai nhánh.
- Dùng
apidog runđể đưa cùng logic vào CI.
Dùng thử Apidog miễn phí và biến các bài kiểm tra API tuyến tính thành các kịch bản có khả năng xử lý điều kiện thực tế.



Top comments (0)