Bạn thực hiện một thay đổi nhỏ cho một endpoint. Mã nguồn biên dịch, tính năng mới hoạt động và bạn triển khai. Hai ngày sau, một ứng dụng di động bắt đầu gặp sự cố vì một trường bạn đã đổi tên trước đây là một chuỗi và bây giờ là một đối tượng. Không ai cố ý làm hỏng nó. Thay đổi trông có vẻ cục bộ. Nhưng thực tế thì không phải vậy.
Kiểm thử hồi quy API tồn tại để phát hiện loại lỗi đó trước khi nó đến tay người dùng. Bạn lưu trữ một bộ kiểm thử mô tả cách API của bạn hoạt động hiện tại, sau đó chạy lại bộ kiểm thử đó sau mỗi thay đổi. Khi một cấu trúc phản hồi, mã trạng thái hoặc giá trị quan trọng khác với những gì bạn đã ghi lại, bộ kiểm thử sẽ thất bại và cho bạn biết chính xác vị trí. Hướng dẫn này bao gồm những gì cần làm đường cơ sở, cách xây dựng một bộ kiểm thử có thể tái sử dụng và cách chạy nó tự động trong CI để việc đổi tên không bao giờ trở thành một sự cố.
Kiểm thử hồi quy API là gì (và tại sao API lại bị hồi quy)
Kiểm thử hồi quy có nghĩa là chạy lại các kiểm thử đã qua để xác nhận rằng hành vi hiện có vẫn được duy trì sau một thay đổi. Đối với API, "hành vi hiện có" là hợp đồng mà người tiêu dùng của bạn phụ thuộc vào: các tuyến đường, mã trạng thái, lược đồ phản hồi và các giá trị trong các trường quan trọng.
API bị hồi quy vì những lý do thông thường. Ai đó đổi tên một trường JSON. Một quá trình tái cấu trúc thay đổi mã 200 thành 204. Một quy tắc xác thực mới từ chối đầu vào trước đây được chấp nhận. Một bản nâng cấp ORM ngầm thay đổi định dạng ngày tháng. Một bản cập nhật phụ thuộc làm thay đổi thông báo lỗi mà một client phân tích cú pháp. Không có thay đổi nào trong số này xuất hiện dưới dạng lỗi biên dịch. Chúng xuất hiện dưới dạng tích hợp bị hỏng, và thường chỉ đối với một tập hợp con của các bên gọi.
Sự khác biệt quan trọng ở đây: kiểm thử hồi quy API hẹp hơn so với kiểm thử hồi quy phần mềm nói chung. Bạn không xác minh lại logic nghiệp vụ trên toàn bộ ứng dụng. Bạn đang kiểm tra xem giao diện HTTP, phần mà các hệ thống khác kết nối, có bị thay đổi hay không. Sự tập trung này là điều làm cho việc chạy nó trên mỗi commit trở nên rẻ.
Những gì cần làm đường cơ sở
Một bộ kiểm thử hồi quy chỉ tốt khi nó xác nhận được những gì quan trọng. Xác nhận quá ít có thể bỏ sót những lỗi thực sự. Xác nhận quá nhiều sẽ khiến mọi thay đổi có chủ ý đều làm bộ kiểm thử báo lỗi. Hãy nhắm đến những trường mà người tiêu dùng thực sự sẽ nhận thấy.
Hãy làm đường cơ sở cho bốn lớp sau:
- Mã trạng thái. Mỗi endpoint phải trả về một trạng thái đã biết cho các đầu vào đã biết. Một mã
200trở thành500, hoặc một201trở thành200, là một hồi quy ngay cả khi phần thân phản hồi trông vẫn ổn. - Lược đồ phản hồi. Cấu trúc và kiểu dữ liệu của phản hồi. Tên trường, lồng nhau, và liệu một giá trị là chuỗi, số, mảng hay đối tượng. Sự lệch lược đồ là lỗi âm thầm phổ biến nhất.
- Các giá trị trường quan trọng. Không phải mọi giá trị, mà là những giá trị có ý nghĩa hợp đồng: một
idphải có mặt, một enumstatusphải nằm trong một tập hợp đã biết, mộttotalphải là một số. - Hợp đồng. Mối quan hệ giữa đặc tả OpenAPI của bạn và phản hồi trực tiếp. Nếu đặc tả nói rằng
emaillà bắt buộc và API ngừng trả về nó, đó là một vi phạm hợp đồng. Xem kiểm thử hợp đồng API để biết cách biến đặc tả thành nguồn đáng tin cậy.
Một quy tắc hữu ích: xác nhận những gì có thể làm hỏng client, chứ không phải những gì hiện có trong payload hôm nay. Một dấu thời gian createdAt thay đổi theo mỗi yêu cầu, vì vậy hãy khóa kiểu và định dạng của nó, không phải giá trị của nó.
Dưới đây là một tập hợp tối thiểu các xác nhận cho một endpoint duy nhất, được viết dưới dạng các kiểm tra đơn giản bạn sẽ chạy đối với một phản hồi:
GET /v1/users/42 -> 200
body.id phải có mặt, kiểu số
body.email phải có mặt, kiểu chuỗi, khớp với định dạng email
body.status là một trong ["active", "pending", "suspended"]
body.roles kiểu mảng
response time < 800 ms
Năm dòng này mô tả hợp đồng. Nếu bất kỳ dòng nào trong số đó thất bại sau một thay đổi, bạn có một hồi quy. Để xử lý sâu hơn về việc viết các kiểm tra đối với phần thân phản hồi, hãy xem các xác nhận API.
Kiểm thử hồi quy thủ công so với tự động
Bạn có thể kiểm thử hồi quy thủ công. Sau một thay đổi, bạn mở client API của mình, phát lại một vài yêu cầu đã lưu và xem xét các phản hồi. Điều này hoạt động tốt với một endpoint nhưng lại không hiệu quả với mười endpoint. Con người thường bỏ qua những trường hợp nhàm chán, và chính những trường hợp nhàm chán đó là nơi các lỗi hồi quy ẩn nấp. Các kiểm tra thủ công cũng không thể chạy vào lúc 2 giờ sáng khi một công việc được lên lịch hợp nhất bản cập nhật phụ thuộc.
Kiểm thử hồi quy tự động loại bỏ yếu tố con người khỏi quy trình. Bạn ghi lại bộ kiểm thử một lần, sau đó một máy sẽ chạy lại nó trên mỗi lần push, mỗi pull request và mỗi lần triển khai. Giá trị không phải là tốc độ trên một lần chạy duy nhất. Mà là bộ kiểm thử chạy mỗi lần, mà không cần ai quyết định liệu nó có đáng công sức hay không.
Sự đánh đổi là công việc ban đầu. Bạn phải xây dựng bộ kiểm thử và duy trì nó. Chi phí bảo trì đó là có thật, nhưng nó nhỏ hơn chi phí của một sự cố sản xuất mà một bài kiểm thử kéo dài năm giây lẽ ra đã có thể phát hiện được.
| Thủ công | Tự động | |
|---|---|---|
| Chạy trên mỗi thay đổi | Không, phụ thuộc vào kỷ luật | Có, theo mặc định |
| Phạm vi bao phủ | Một vài endpoint | Toàn bộ bộ kiểm thử |
| Chi phí cho mỗi lần chạy | Phút thời gian của con người | Giây tính toán |
| Bắt lỗi lúc 2 giờ sáng | Không | Có |
| Nỗ lực ban đầu | Thấp | Trung bình |
Đối với bất cứ thứ gì ngoài một dự án nhỏ, hãy tự động hóa nó.
Xây dựng một bộ kiểm thử hồi quy có thể tái sử dụng
Một bộ kiểm thử hồi quy là một tập hợp các yêu cầu đã lưu, mỗi yêu cầu có các xác nhận, được nhóm lại để bạn có thể chạy chúng cùng nhau. Mục tiêu là tái sử dụng: xây dựng nó một lần, chạy nó mãi mãi, mở rộng nó khi bạn thêm các endpoint.
Cấu trúc bộ kiểm thử để nó tồn tại qua các thay đổi:
- Nhóm theo tài nguyên, không theo tính năng. Đặt tất cả các kiểm thử
/userscùng nhau, tất cả các kiểm thử/orderscùng nhau. Khi bạn tác động đến dịch vụ người dùng, bạn biết nhóm nào cần theo dõi. - Sử dụng biến môi trường cho bất cứ thứ gì thay đổi. URL cơ sở, mã thông báo xác thực và ID khách thuê thuộc về một môi trường, không nên được mã hóa cứng trong mỗi yêu cầu. Điều đó cho phép cùng một bộ kiểm thử chạy đối với môi trường cục bộ, staging và sản xuất bằng cách thay đổi một cài đặt.
- Xâu chuỗi các yêu cầu phụ thuộc lẫn nhau. Một luồng thực tế tạo một tài nguyên, đọc lại nó, cập nhật nó và xóa nó. Trích xuất
idtừ phản hồi tạo và truyền nó cho yêu cầu tiếp theo. Điều này bắt lỗi hồi quy chỉ xuất hiện trong một chuỗi, chứ không phải riêng lẻ. Đây là nơi kiểm thử hồi quy trùng lặp với kiểm thử tích hợp API. - Kiểm thử các trường hợp biên bằng dữ liệu. Thay vì mười yêu cầu gần như giống hệt nhau, hãy viết một yêu cầu và cung cấp cho nó một bảng đầu vào: các giá trị hợp lệ, giá trị trống, giá trị biên và các giá trị lỗi đã biết. Mỗi hàng trở thành một trường hợp kiểm thử. Các kiểm thử dựa trên dữ liệu giúp bộ kiểm thử nhỏ gọn trong khi vẫn mở rộng phạm vi bao phủ.
Đây là những gì một bảng dữ liệu cho một kiểm thử xác thực duy nhất có thể trông như thế nào dưới dạng CSV:
email,expectedStatus
alice@example.com,201
bob@test.co,201
not-an-email,422
,422
a@b,422
Một yêu cầu, năm trường hợp, năm xác nhận về mã trạng thái. Thêm một hàng khi bạn tìm thấy một trường hợp biên mới, và bộ kiểm thử sẽ mở rộng mà không cần thêm mã mới.
Giữ cho bộ kiểm thử nhanh. Một bộ kiểm thử hồi quy mất hai mươi phút sẽ bị bỏ qua. Giả lập các phụ thuộc bên thứ ba chậm, chạy các yêu cầu độc lập song song nếu công cụ của bạn cho phép, và dành toàn bộ luồng đầu cuối cho một lần chạy hàng đêm nhỏ hơn, chậm hơn.
Chạy bộ kiểm thử trên mỗi thay đổi trong CI
Một bộ kiểm thử hồi quy chỉ chạy trên máy tính xách tay của bạn chỉ bảo vệ máy tính xách tay của bạn. Mục đích là chạy nó trong tích hợp liên tục (CI), trên cùng các sự kiện có thể gây ra hồi quy: pull requests và các lần hợp nhất vào nhánh chính của bạn.
Mẫu hình này giống nhau trên tất cả các hệ thống CI. Cài đặt một trình chạy không giao diện (headless runner), trỏ nó vào bộ kiểm thử đã lưu của bạn, và làm thất bại bản dựng nếu bất kỳ xác nhận nào không thành công. Apidog cung cấp một trình chạy dòng lệnh cho chính mục đích này. Cài đặt nó bằng Node:
npm install -g apidog-cli
Sau đó chạy một kịch bản kiểm thử hoặc bộ kiểm thử đã lưu bằng ID của nó, đối với một môi trường đã chọn, và xuất báo cáo:
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t 123456 \
-e 789012 \
-r cli,html,junit
Phân tích chi tiết:
--access-tokenxác thực lần chạy. Lưu trữ mã thông báo dưới dạng bí mật CI, không bao giờ trong repo.-tlà ID của kịch bản, thư mục hoặc bộ kiểm thử để chạy.-elà ID môi trường, vì vậy cùng một bộ kiểm thử có thể nhắm mục tiêu staging hoặc production bằng cách thay đổi một giá trị.-rliệt kê các định dạng báo cáo.cliin ra console,htmltạo báo cáo dễ đọc vàjunitxuất XML mà CI của bạn có thể phân tích cú pháp để hiển thị kết quả đậu/rớt cho mỗi kiểm thử.
Trình chạy là không giao diện (headless). Nó phù hợp với bất kỳ bước CI nào có thể chạy Node, vì vậy cùng một lệnh hoạt động trong GitHub Actions, GitLab CI, Jenkins hoặc CircleCI. Dưới đây là một job GitHub Actions chạy bộ kiểm thử trên mỗi pull request:
name: API Regression
on: [pull_request]
jobs:
regression:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: '22'
- run: npm install -g apidog-cli
- run: |
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t 123456 \
-e 789012 \
-r cli,junit
env:
APIDOG_ACCESS_TOKEN: ${{ secrets.APIDOG_ACCESS_TOKEN }}
Khi một kịch bản thất bại, trình chạy thoát với mã không bằng không và job chuyển sang màu đỏ. Pull request bị chặn cho đến khi có người xem xét. Để có một pipeline hoàn chỉnh có thể sao chép và thêm các mẫu CI, hãy xem Apidog CLI cho CI/CD và cách tự động hóa kiểm thử API trong GitHub Actions.
Nếu bạn cung cấp tệp dữ liệu cho bộ kiểm thử, hãy truyền nó bằng -d:
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t 123456 \
-e 789012 \
-d ./test-data/emails.csv \
-r cli,junit
Kiểm thử một nhánh tính năng có phiên bản API riêng của nó? Thêm --branch để chạy với bộ kiểm thử đã lưu của nhánh đó thay vì mặc định. Để giữ lịch sử các lần chạy trên đám mây, hãy thêm cờ --upload-report trần.
So sánh lược đồ và hợp đồng
Các xác nhận bắt lỗi hồi quy trong hành vi. So sánh lược đồ bắt lỗi hồi quy trong định nghĩa, thường là trước khi bạn triển khai.
Ý tưởng: đặc tả OpenAPI của bạn là một tệp có phiên bản trong kho lưu trữ của bạn. Khi ai đó chỉnh sửa nó, bạn sẽ so sánh đặc tả mới với đặc tả trước đó và phân loại thay đổi. Thêm một trường tùy chọn là an toàn. Xóa một trường, đổi tên một trường, thắt chặt một kiểu dữ liệu hoặc biến một trường tùy chọn thành bắt buộc là một thay đổi gây lỗi. Một công cụ so sánh có thể gắn cờ các thay đổi gây lỗi trong pull request, để người đánh giá thấy "điều này xóa user.phone" thay vì một khối YAML.
Kết hợp điều đó với kiểm thử hợp đồng đối với API trực tiếp. Trên mỗi lần chạy, xác thực các phản hồi thực tế so với lược đồ hiện tại. Nếu đặc tả hứa hẹn một trường mà API không còn trả về, hoặc API trả về một kiểu dữ liệu mà đặc tả cấm, kiểm tra sẽ thất bại. Đây là cơ chế bảo vệ hai chiều: so sánh đặc tả phát hiện các chỉnh sửa cố ý đối với hợp đồng, và kiểm thử hợp đồng phát hiện mã nguồn đang lệch khỏi hợp đồng.
Các thay đổi gây lỗi không phải lúc nào cũng là lỗi. Đôi khi bạn cố ý xóa một trường. Mục đích của việc so sánh là làm cho quyết định đó trở nên rõ ràng và đưa nó qua quy trình tạo phiên bản và ngừng hỗ trợ của bạn thay vì gây bất ngờ cho client. Xem cách tạo phiên bản và ngừng hỗ trợ API ở quy mô lớn để xử lý các thay đổi bạn thực hiện có chủ đích.
Cách Apidog chạy các bộ kiểm thử hồi quy
Apidog bao gồm các phần được mô tả ở trên tại một nơi, giúp giữ bộ kiểm thử và đặc tả gần nhau.
Bạn xây dựng các kịch bản kiểm thử một cách trực quan: xâu chuỗi các yêu cầu, trích xuất giá trị từ một phản hồi sang yêu cầu tiếp theo và đính kèm các xác nhận về trạng thái, lược đồ và giá trị trường. Vì thiết kế API và các kiểm thử nằm trong cùng một dự án, bạn có thể xác thực phản hồi so với lược đồ đã lưu của endpoint mà không cần viết lại lược đồ hai lần. Khi thiết kế thay đổi, lược đồ mà các kiểm thử kiểm tra cũng thay đổi theo.
Đối với các trường hợp dựa trên dữ liệu, hãy đính kèm một tập dữ liệu CSV hoặc JSON vào một kịch bản và Apidog sẽ chạy một trường hợp cho mỗi hàng. Lưu các kịch bản liên quan vào một bộ kiểm thử để một lần chạy duy nhất có thể kiểm tra toàn bộ tài nguyên hoặc luồng.
Trình chạy apidog-cli đưa các bộ kiểm thử đã lưu đó vào CI ở chế độ không giao diện, như đã trình bày ở trên. Nó chạy các kịch bản và bộ kiểm thử đã lưu. Nó không phải là một trình gửi yêu cầu tương tác và cũng không phải là một trình tạo tải. Nó thực hiện một công việc: phát lại bộ kiểm thử hồi quy của bạn và báo cáo những gì đã qua. Phạm vi hẹp đó là điều cho phép nó tích hợp vào bất kỳ bước CI nào có khả năng chạy Node. Để biết thêm về CLI cùng với quy trình làm việc có script, hãy xem hướng dẫn pipeline CI/CD của Apidog CLI.
Quy trình làm việc khởi đầu
Dưới đây là một chuỗi các bước bạn có thể áp dụng ngay trong tuần này mà không cần xây dựng lại chiến lược kiểm thử của mình:
- Chọn năm endpoint được gọi nhiều nhất của bạn. Rủi ro hồi quy tập trung ở những nơi có lưu lượng truy cập. Bắt đầu từ đó.
- Lưu một yêu cầu cho mỗi endpoint với các xác nhận. Mã trạng thái, lược đồ phản hồi, và hai hoặc ba trường quan trọng mỗi loại. Đây là đường cơ sở của bạn.
- Thêm một luồng chuỗi. Tạo, đọc, cập nhật, xóa trên tài nguyên cốt lõi của bạn. Điều này bắt được các lỗi hồi quy giữa các yêu cầu mà các kiểm thử riêng lẻ bỏ sót.
- Thêm một bảng dữ liệu vào một endpoint có nhiều xác thực. Một vài đầu vào hợp lệ, trống và không hợp lệ.
- Tích hợp nó vào CI trên các pull request. Cài đặt
apidog-cli, chạy bộ kiểm thử với-r junit, và chặn các lần hợp nhất khi thất bại. - Mở rộng bộ kiểm thử khi một lỗi thoát ra ngoài. Mỗi lỗi hồi quy sản xuất lọt qua sẽ trở thành một trường hợp kiểm thử mới. Bộ kiểm thử trở nên mạnh hơn từ chính những lỗi mà nó bỏ sót.
Các bước từ một đến bốn chỉ mất một buổi chiều. Bước năm là một tệp CI duy nhất. Sau đó, bộ kiểm thử tự chạy và bạn chỉ mở rộng nó khi thực tế dạy cho bạn một chế độ lỗi mới. Vòng phản hồi đó là toàn bộ vấn đề: một việc đổi tên lẽ ra đã là một sự cố sẽ trở thành một dấu kiểm đỏ trên một pull request.
Câu hỏi thường gặp
- Kiểm thử hồi quy API khác với kiểm thử hồi quy nói chung như thế nào? Kiểm thử hồi quy nói chung xác minh lại hành vi ứng dụng trên toàn bộ hệ thống, bao gồm giao diện người dùng và logic nghiệp vụ. Kiểm thử hồi quy API thu hẹp phạm vi đó vào giao diện HTTP: các tuyến đường, mã trạng thái, lược đồ phản hồi và các giá trị trường quan trọng. Sự tập trung hẹp này giúp nó đủ nhanh để chạy trên mỗi commit và nó nhắm mục tiêu chính xác những gì các hệ thống khác kết nối đến.
- Tôi nên chạy bộ kiểm thử hồi quy bao lâu một lần? Trên mỗi thay đổi có thể ảnh hưởng đến API. Trong thực tế, điều đó có nghĩa là mỗi pull request và mỗi lần hợp nhất vào nhánh chính của bạn, đều được chạy tự động trong CI. Duy trì một bộ kiểm thử cốt lõi nhanh cho các pull request và một lần chạy đầu cuối lớn hơn cho các bản dựng hàng đêm để kiểm tra trên mỗi commit vẫn nhanh chóng.
- Tôi nên xác nhận những gì để tránh một bộ kiểm thử dễ vỡ? Xác nhận những gì có thể làm hỏng client. Đặt cố định mã trạng thái, cấu trúc và kiểu phản hồi, và các giá trị của các trường có ý nghĩa hợp đồng như ID và enum trạng thái. Đối với các giá trị thay đổi theo mỗi yêu cầu, chẳng hạn như dấu thời gian, hãy xác nhận kiểu và định dạng, không phải giá trị cố định. Việc xác nhận quá mức trên dữ liệu không ổn định là nguyên nhân chính gây ra các lỗi sai.
- Tôi có thể chạy kiểm thử hồi quy API mà không cần viết mã không? Có. Các công cụ như Apidog cho phép bạn xây dựng các kịch bản và xác nhận một cách trực quan, sau đó chạy chúng ở chế độ không giao diện trong CI bằng
apidog-cli. Bạn lưu bộ kiểm thử một lần thông qua giao diện và trình chạy dòng lệnh sẽ phát lại nó trong pipeline của bạn, vì vậy các kiểm thử chạy tự động mà không cần một test harness viết tay. - Làm thế nào để xử lý các thay đổi gây lỗi có chủ đích? Hãy đưa chúng qua quy trình tạo phiên bản và ngừng hỗ trợ của bạn thay vì để chúng xuất hiện dưới dạng các lỗi kiểm thử bất ngờ. Sử dụng so sánh lược đồ để gắn cờ thay đổi trong quá trình xem xét, tạo phiên bản endpoint hoặc thêm trường đó dưới dạng tùy chọn trước, và cập nhật đường cơ sở hồi quy một cách có chủ đích sau khi thay đổi được dự định và thông báo cho người tiêu dùng.
