DEV Community

Cover image for Cách kiểm thử API upload file (multipart/form-data) trong Apidog
Sebastian Petrus
Sebastian Petrus

Posted on • Originally published at apidog.com

Cách kiểm thử API upload file (multipart/form-data) trong Apidog

Bạn đã xây dựng một endpoint nhận tệp: người dùng tải ảnh đại diện lên POST /avatars, hoặc ứng dụng đẩy PDF đã ký lên POST /documents. Bây giờ, bạn cần kiểm tra nó qua HTTP: chọn một tệp thực, đính kèm vào trường biểu mẫu, gửi yêu cầu và xác minh phản hồi.

Thử Apidog ngay hôm nay

Tải tệp dùng multipart/form-data, không phải JSON. Vì vậy, bạn không thể chỉ dán nội dung vào body rồi nhấn gửi. Bạn cần một công cụ có thể đính kèm trường tệp và một quy trình kiểm thử có thể tìm thấy tệp khi chạy lại trong Runner hoặc CLI. Apidog hỗ trợ cả hai.

Bài viết này tập trung vào quy trình triển khai:

  • Gửi một tệp đơn lẻ.
  • Gửi tệp kèm JSON.
  • Xác nhận phản hồi.
  • Chạy lại bài kiểm thử trong Runner hoặc CLI khi tệp không còn ở máy cục bộ.

Nếu cần tìm hiểu cấu trúc multipart trước, xem bài tải tệp trong API. Tài liệu MDN về FormData cũng hữu ích khi bạn làm việc ở phía trình duyệt.

multipart/form-data là gì và tại sao tác vụ tải tệp cần nó

Body của một yêu cầu API có thể là form-data, x-www-form-urlencoded, JSON, XML, raw hoặc binary. Trong phần lớn trường hợp, bạn sẽ dùng JSON. Tải tệp là ngoại lệ.

Khi chọn form-data, Apidog tạo body với tiêu đề:

Content-Type: multipart/form-data
Enter fullscreen mode Exit fullscreen mode

Body được chia thành nhiều phần. Mỗi phần có tên và dữ liệu riêng:

  • Một phần có thể là chuỗi như title.
  • Một phần có thể là byte thô của ảnh hoặc PDF.
  • Các phần này được gửi trong cùng một HTTP request.

Người họ hàng gần của nó là x-www-form-urlencoded. Dù đều có dạng khóa-giá trị, định dạng này chỉ phù hợp cho các trường văn bản ngắn, không chứa tệp.

Quy tắc chọn nhanh:

Trường hợp Body nên dùng
Chỉ có dữ liệu JSON JSON
Form đơn giản, không có tệp x-www-form-urlencoded
Có ảnh, PDF, video hoặc tệp bất kỳ form-data

Trong form-data, mỗi tham số có kiểu riêng như string, integer hoặc file. Điểm quan trọng là: khi đặt kiểu thành file, Apidog sẽ đính kèm nội dung tệp thay vì gửi đường dẫn dưới dạng văn bản.

Gửi một tệp tải lên duy nhất và xác nhận phản hồi

Giả sử bạn đang kiểm thử:

POST /avatars
Enter fullscreen mode Exit fullscreen mode

Endpoint nhận trường avatar chứa ảnh và trả JSON với URL ảnh đã lưu.

1. Chọn Body là form-data

Trong Apidog:

  1. Đặt method là POST.
  2. Nhập URL endpoint, ví dụ https://api.example.com/avatars.
  3. Mở tab Body.
  4. Chọn form-data.

Apidog sẽ tự đặt Content-Type: multipart/form-data.

2. Thêm trường tệp

Thêm một hàng tham số:

Key Type Value
avatar file Chọn tệp

Đổi kiểu của trường avatar từ string sang file. Ô giá trị sẽ chuyển thành trình chọn tệp.

3. Chọn tệp cục bộ

Nhấp Upload trên hàng avatar, sau đó chọn tệp, ví dụ:

jane-profile.png
Enter fullscreen mode Exit fullscreen mode

Apidog lưu đường dẫn cục bộ đến tệp, không lưu byte của tệp trên đám mây.

4. Gửi request

Nhấn Send. Apidog sẽ:

  1. Đọc tệp từ đường dẫn cục bộ.
  2. Tạo multipart body.
  3. Gửi request đến endpoint.

Một phản hồi thành công có thể như sau:

{
  "id": "usr_8842",
  "avatarUrl": "https://cdn.example.com/avatars/usr_8842.png",
  "sizeBytes": 48210,
  "contentType": "image/png"
}
Enter fullscreen mode Exit fullscreen mode

5. Thêm assertions

Status 200 không đủ để chứng minh endpoint hoạt động đúng. Hãy thêm post-request assertions để xác minh dữ liệu quan trọng:

status code == 200
$.avatarUrl exists
$.contentType == "image/png"
Enter fullscreen mode Exit fullscreen mode

Các assertion này kiểm tra:

  • Request trả về HTTP 200.
  • JSON có trường avatarUrl.
  • Máy chủ nhận đúng loại MIME của tệp.

Xem thêm hướng dẫn xác nhận API để biết các toán tử và cách dùng JSONPath.

Tương đương với curl:

curl -X POST https://api.example.com/avatars \
  -F "avatar=@jane-profile.png"
Enter fullscreen mode Exit fullscreen mode

Cờ -F tạo multipart request, còn @ yêu cầu curl đọc nội dung từ tệp. Trường file trong Apidog thực hiện cùng chức năng đó qua giao diện.

Gửi một tệp và JSON cùng nhau

Các endpoint thực tế thường cần cả tệp lẫn metadata. Ví dụ:

POST /documents
Enter fullscreen mode Exit fullscreen mode

Endpoint có thể nhận:

  • Tệp PDF.
  • Tiêu đề.
  • Danh mục.
  • Danh sách thẻ.

Trường dữ liệu đơn giản

Với dữ liệu vô hướng, thêm các hàng form-data bên cạnh trường tệp:

Key Type Ví dụ
file file q3-invoice.pdf
title string Q3 Invoice
category string billing

Tất cả được gửi trong một multipart request.

Metadata có cấu trúc

Nếu metadata là object lồng nhau hoặc mảng, gửi JSON dưới dạng một trường string:

Key Type Value
file file q3-invoice.pdf
metadata string JSON bên dưới
{
  "title": "Q3 Invoice",
  "category": "billing",
  "tags": ["invoice", "2026", "paid"]
}
Enter fullscreen mode Exit fullscreen mode

Máy chủ sẽ:

  1. Đọc PDF từ phần file.
  2. Phân tích JSON từ phần metadata.

Đây là mẫu multipart phổ biến. Ví dụ, tài liệu tải tệp của Stripe minh họa một endpoint nhận phần tệp cùng các trường dữ liệu khác.

Nếu đang chuyển từ Postman, xem hướng dẫn tải tệp và dữ liệu JSON trong Postman.

Đính kèm nhiều tệp

Không cần chế độ đa tệp riêng. Chỉ cần thêm nhiều trường kiểu file:

Key Type
file file
thumbnail file

Mỗi trường có nút Upload riêng.

Biến request thành kịch bản kiểm thử có thể lặp lại

Một lần gửi request chỉ chứng minh endpoint hoạt động tại thời điểm đó. Để phát hiện lỗi hồi quy, hãy lưu request trong test scenario.

Ví dụ một luồng kiểm thử:

  1. Gọi POST /avatars.
  2. Lấy id từ response.
  3. Gọi GET /users/{id}.
  4. Xác minh avatarUrl đã được lưu.

Bạn có thể lưu bước tải tệp như một bước trong scenario, sau đó truyền id sang bước tiếp theo. Hướng dẫn cách viết kịch bản kiểm thử với Apidog trình bày cách nối các bước và truyền giá trị giữa chúng.

Sau khi tạo scenario, bạn có thể:

Tuy nhiên, có một vấn đề quan trọng: máy của bạn có tệp, nhưng Runner hoặc CLI có thể không có.

Cái bẫy: tác vụ tải tệp chạy ở nơi khác

Apidog lưu đường dẫn tệp, không lưu tệp. Trên máy cục bộ, điều này thường không gây vấn đề vì đường dẫn vẫn hợp lệ.

Ví dụ, bạn chọn:

/Users/jane/pics/jane-profile.png
Enter fullscreen mode Exit fullscreen mode

Đường dẫn này chỉ tồn tại trên máy của bạn. Khi cùng request chạy ở máy khác, nó có thể không tìm thấy tệp.

Bạn thường gặp vấn đề này trong hai trường hợp.

Hợp tác nhóm

Đồng đội có thể mở request của bạn và thấy đường dẫn:

/Users/jane/pics/jane-profile.png
Enter fullscreen mode Exit fullscreen mode

Nhưng họ không thể gửi request nếu tệp không tồn tại trên máy của họ.

Cách xử lý: mỗi người cần có bản sao tệp và đặt đường dẫn phù hợp trên máy của mình, hoặc dùng biến môi trường cho đường dẫn.

Chạy bằng Runner hoặc CLI

Kịch bản có thể chạy thành công cục bộ nhưng thất bại trên Runner hoặc CI vì Runner không có tệp tại đường dẫn cục bộ của bạn.

Nguyên tắc xử lý là:

Tệp phải tồn tại trên máy thực hiện request, và trường tệp phải trỏ đến đường dẫn hợp lệ trên máy đó.

Thiết lập tệp cho Runner

Runner đọc tệp từ thư mục máy chủ đã được mount vào volume bằng cờ -v.

Quy trình:

  1. Mount thư mục chứa fixture khi triển khai Runner.
  2. Sao chép tệp tải lên vào thư mục đó.
  3. Mở bước tải tệp trong scenario.
  4. Nhấp Batch Edit.
  5. Thay thế đường dẫn tệp bằng đường dẫn trong môi trường Runner.

Ví dụ:

/opt/runner/jane-profile.png
Enter fullscreen mode Exit fullscreen mode

Thiết lập tệp cho CLI

Với CLI, nguyên tắc tương tự:

  1. Đặt tệp trên máy chạy CLI hoặc CI runner.
  2. Dùng Batch Edit để cập nhật đường dẫn.
  3. Hoặc tốt hơn, dùng biến môi trường.

Ví dụ:

/opt/apidog/runner/jane-profile.png
Enter fullscreen mode Exit fullscreen mode

Dùng biến thay vì mã hóa cứng đường dẫn

Không nên hard-code đường dẫn trong bước kiểm thử. Thay vào đó, dùng biến, ví dụ:

{{avatar_file_path}}
Enter fullscreen mode Exit fullscreen mode

Sau đó đặt giá trị biến theo môi trường:

Môi trường avatar_file_path
Local /Users/jane/pics/jane-profile.png
Runner /opt/runner/jane-profile.png
CI /opt/apidog/runner/jane-profile.png

Nhờ đó, scenario không cần thay đổi khi chạy ở môi trường khác.

Runner chỉ truy cập được tệp trong thư mục đã được mount bằng -v khi triển khai. Nếu tệp nằm ngoài vùng mount, không có đường dẫn nào có thể đọc được nó.

Xem tài liệu Apidog về các yêu cầu tải tệp để biết chi tiết về mount volume và Batch Edit.

Tự động hóa quy trình với Apidog CLI

Sau khi lưu scenario, bạn có thể chạy nó ở chế độ headless trong CI.

Cài đặt CLI:

npm install -g apidog-cli
Enter fullscreen mode Exit fullscreen mode

Xác thực bằng access token:

apidog login --with-token <YOUR_ACCESS_TOKEN>
Enter fullscreen mode Exit fullscreen mode

Chạy scenario theo ID và môi trường:

apidog run --access-token $APIDOG_ACCESS_TOKEN -t <scenario_id> -e <env_id> -r cli
Enter fullscreen mode Exit fullscreen mode

Trong đó:

  • -t: ID của test scenario.
  • -e: ID của environment.
  • -r: reporter, có thể là cli, html hoặc junit.

Bạn có thể chỉ định nhiều reporter, phân tách bằng dấu phẩy.

CLI chạy scenario từ cloud project và trả kết quả pass/fail qua exit code, vì vậy nó phù hợp để kiểm soát pipeline CI.

Xem thêm hướng dẫn cài đặt Apidog CLI.

Lưu ý quan trọng: CLI vẫn cần tệp tồn tại trên máy đang chạy. Trước khi chạy:

  1. Chuẩn bị tệp trên CI runner.
  2. Đặt đúng đường dẫn bằng Batch Edit hoặc biến môi trường.
  3. Sau đó mới chạy scenario.

Nếu bỏ qua bước này, request tải tệp sẽ thất bại dù các bước khác trong scenario vẫn đúng. Để chạy theo nhiều bộ dữ liệu, xem kiểm thử dựa trên dữ liệu với Apidog CLI.

Câu hỏi thường gặp

Tại sao đồng đội của tôi không thể gửi request tải tệp?

Apidog lưu đường dẫn tệp cục bộ, không lưu tệp trên đám mây. Đường dẫn của bạn trỏ đến ổ đĩa của bạn, không phải máy của đồng đội.

Hãy yêu cầu họ:

  1. Tải hoặc sao chép tệp về máy.
  2. Chọn lại tệp trong trường file.
  3. Hoặc cấu hình biến đường dẫn riêng cho môi trường của họ.

Cơ chế tương tự cũng áp dụng cho các bài kiểm thử theo lịch trình và Runner.

Làm cách nào để gửi JSON cùng với tệp trong một request?

Giữ body là form-data:

  1. Thêm trường tệp với kiểu file.
  2. Thêm trường metadata với kiểu string.
  3. Dán JSON vào giá trị của trường metadata.

Máy chủ sẽ nhận tệp và chuỗi JSON trong hai phần riêng của multipart request.

Tôi nên dùng đường dẫn nào cho tệp trong Runner?

Dùng đường dẫn bên trong thư mục đã mount vào Runner bằng cờ -v.

Ví dụ:

/opt/runner/yourfile.jpg
Enter fullscreen mode Exit fullscreen mode

Sao chép tệp vào thư mục đó, sau đó dùng Batch Edit để đặt giá trị trường tệp.

Với CLI, một đường dẫn tương tự có thể là:

/opt/apidog/runner/yourfile.jpg
Enter fullscreen mode Exit fullscreen mode

Apidog có giới hạn kích thước hoặc loại tệp không?

Việc tạo request trong Apidog tập trung vào cách gửi multipart và đọc tệp từ máy cục bộ. Giới hạn kích thước và loại tệp thực tế do API của bạn quyết định.

Hãy kiểm tra validation ở phía máy chủ và thêm assertion cho các trường hợp:

  • Tệp vượt kích thước cho phép.
  • MIME type không hợp lệ.
  • Phần mở rộng không được hỗ trợ.
  • Tệp bị từ chối.

Nên dùng form-data hay x-www-form-urlencoded để tải tệp?

Dùng form-data.

Nó ánh xạ tới multipart/form-data và được thiết kế để mang tệp. x-www-form-urlencoded chỉ phù hợp cho các form đơn giản gồm trường văn bản ngắn.

Tóm tắt

Kiểm thử tải tệp có hai phần chính:

  1. Xây dựng multipart request đúng cách.
  2. Đảm bảo tệp tồn tại ở bất kỳ môi trường nào chạy bài kiểm thử.

Trong Apidog, quy trình cơ bản là:

  1. Chọn Body là form-data.
  2. Đặt kiểu trường thành file.
  3. Chọn tệp bằng Upload.
  4. Gửi JSON bổ sung dưới dạng trường string nếu cần.
  5. Gửi request và thêm assertions.
  6. Khi chạy bằng Runner hoặc CLI, chuẩn bị tệp trên máy đích.
  7. Dùng Batch Edit hoặc biến để đặt đường dẫn theo từng môi trường.

Muốn thử với endpoint của bạn? Tải Apidog, tạo request form-data, trỏ đến endpoint tải tệp và kiểm tra phản hồi.

Top comments (0)