Bạn vừa đổi tên một trường trong một endpoint. Code build thành công, tính năng mới chạy ổn, deployment không lỗi. Hai ngày sau, ứng dụng mobile crash vì trường đó trước đây là chuỗi nhưng giờ thành object. Đây là lỗi hồi quy API: thay đổi tưởng như cục bộ nhưng phá vỡ hợp đồng mà client đang phụ thuộc.
Kiểm thử hồi quy API giúp bắt những lỗi này trước khi chúng đến tay người dùng. Bạn lưu một bộ kiểm thử mô tả hành vi hiện tại của API, sau đó chạy lại bộ đó sau mỗi thay đổi. Nếu cấu trúc response, status code hoặc giá trị quan trọng khác với baseline, pipeline sẽ fail và chỉ ra endpoint bị ảnh hưởng.
Kiểm thử hồi quy API là gì?
Kiểm thử hồi quy nghĩa là chạy lại các test đã từng pass để xác nhận hành vi hiện có vẫn được giữ nguyên sau thay đổi.
Với API, “hành vi hiện có” chính là hợp đồng HTTP mà client phụ thuộc vào:
- Route
- Method
- Status code
- Response schema
- Field name
- Data type
- Giá trị quan trọng như
id,status,total
API thường bị hồi quy vì các thay đổi nhỏ:
- Đổi tên một field JSON
- Refactor làm
200thành204 - Rule validation mới từ chối input cũ
- ORM upgrade làm đổi format ngày tháng
- Dependency update làm đổi error message mà client đang parse
Những lỗi này không xuất hiện ở compile time. Chúng xuất hiện khi client tích hợp với API.
Điểm khác biệt: kiểm thử hồi quy API hẹp hơn kiểm thử hồi quy phần mềm nói chung. Bạn không kiểm lại toàn bộ business logic hay UI. Bạn chỉ kiểm phần giao diện HTTP mà hệ thống khác gọi vào. Vì phạm vi hẹp, bộ test có thể chạy trên mỗi commit hoặc pull request.
Nên baseline những gì?
Một bộ regression test tốt không nên assert mọi thứ trong payload. Hãy assert những gì có thể làm hỏng client.
Baseline nên gồm 4 lớp sau.
1. Status code
Mỗi endpoint phải trả về status code đã biết với input đã biết.
Ví dụ:
POST /v1/users -> 201
GET /v1/users/42 -> 200
DELETE /v1/users/42 -> 204
Nếu 201 đổi thành 200, hoặc 200 đổi thành 500, đó là hồi quy ngay cả khi response body vẫn có vẻ hợp lệ.
2. Response schema
Kiểm cấu trúc và kiểu dữ liệu:
- Field có tồn tại không
- Field có bị đổi tên không
- Field là string, number, array hay object
- Object có bị lồng khác đi không
Schema drift là một trong những lỗi hồi quy API phổ biến nhất.
3. Giá trị trường quan trọng
Không cần khóa mọi giá trị. Chỉ assert các giá trị mang ý nghĩa hợp đồng:
-
idphải tồn tại -
emailphải là string đúng format -
statusphải thuộc enum cho phép -
totalphải là number -
rolesphải là array
Ví dụ baseline tối thiểu cho một endpoint:
GET /v1/users/42 -> 200
body.id phải tồn tại, kiểu number
body.email phải tồn tại, kiểu string, đúng format email
body.status là một trong ["active", "pending", "suspended"]
body.roles kiểu array
response time < 800 ms
Nếu bất kỳ dòng nào fail sau một thay đổi, bạn đã có một regression signal rõ ràng.
Để viết assertion cho response body chi tiết hơn, xem các xác nhận API.
4. Hợp đồng API
Nếu bạn có OpenAPI spec, hãy dùng nó làm nguồn sự thật.
Ví dụ:
- Spec nói
emaillà required nhưng API không trả về nữa → contract violation - Spec nói
createdAtlà string date-time nhưng API trả về number → contract violation - Spec nói response là array nhưng API trả về object → contract violation
Xem thêm kiểm thử hợp đồng API để biến OpenAPI spec thành contract test.
Nguyên tắc thực tế:
Assert những gì có thể làm hỏng client, không assert mọi thứ tình cờ có trong payload hôm nay.
Ví dụ createdAt thay đổi theo mỗi request. Đừng assert giá trị cố định. Hãy assert type và format.
Kiểm thử thủ công hay tự động?
Bạn có thể kiểm thử hồi quy thủ công bằng cách mở API client, replay vài request đã lưu và kiểm response bằng mắt. Cách này ổn với một endpoint, nhưng nhanh chóng hỏng khi có nhiều endpoint.
Vấn đề của test thủ công:
- Dễ bỏ sót case nhàm chán
- Không chạy đều trên mỗi thay đổi
- Không chạy lúc 2 giờ sáng khi dependency update được merge
- Không scale khi API tăng số endpoint
Kiểm thử tự động giải quyết bằng cách ghi lại test một lần và chạy lại trên:
- Mỗi push
- Mỗi pull request
- Mỗi merge vào main
- Mỗi deployment
- Job nightly nếu cần full coverage
| Tiêu chí | 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ủ | Vài endpoint | Toàn bộ test suite |
| Chi phí mỗi lần chạy | Phút của con người | Giây tính toán |
| Bắt lỗi ngoài giờ làm việc | Không | Có |
| Nỗ lực ban đầu | Thấp | Trung bình |
Với bất kỳ API nào có client thật, hãy tự động hóa regression test.
Xây dựng bộ kiểm thử hồi quy có thể tái sử dụng
Một regression suite nên là tập hợp các request đã lưu, có assertion, được nhóm để chạy cùng nhau.
Cấu trúc nên hướng tới tái sử dụng.
Nhóm theo tài nguyên
Thay vì nhóm theo feature ticket, hãy nhóm theo resource:
/users
/orders
/payments
/auth
Khi thay đổi user service, bạn biết ngay nhóm test nào cần chú ý.
Dùng biến môi trường
Không hard-code các giá trị thay đổi theo môi trường.
Nên đưa các giá trị này vào environment:
baseUrl
authToken
tenantId
userId
Ví dụ:
{{baseUrl}}/v1/users/{{userId}}
Authorization: Bearer {{authToken}}
Nhờ vậy cùng một suite có thể chạy trên:
- Local
- Staging
- Production smoke test
Xâu chuỗi request phụ thuộc nhau
Một flow thực tế thường là:
POST /users -> tạo user
GET /users/{id} -> đọc lại user
PATCH /users/{id}-> cập nhật user
DELETE /users/{id}-> xóa user
Hãy trích xuất id từ response tạo mới và truyền vào request tiếp theo.
Pseudo flow:
1. POST /v1/users
2. Save body.id as userId
3. GET /v1/users/{{userId}}
4. Assert body.id == {{userId}}
5. PATCH /v1/users/{{userId}}
6. DELETE /v1/users/{{userId}}
Cách này bắt được lỗi chỉ xuất hiện trong chuỗi request, không phải khi test từng endpoint riêng lẻ. Đây là phần giao nhau giữa regression testing và kiểm thử tích hợp API.
Dùng data-driven test cho validation
Nếu một endpoint có nhiều input case, đừng tạo 10 request gần giống nhau. Hãy dùng một request và một bảng dữ liệu.
Ví dụ CSV:
email,expectedStatus
alice@example.com,201
bob@test.co,201
not-an-email,422
,422
a@b,422
Một request, năm test case, năm assertion cho status code.
Khi phát hiện edge case mới, chỉ cần thêm một dòng vào CSV.
Giữ suite đủ nhanh
Regression suite mất 20 phút sẽ dễ bị bỏ qua. Hãy tối ưu để suite chạy nhanh trên pull request:
- Mock dependency bên thứ ba chậm
- Chạy request độc lập song song nếu công cụ hỗ trợ
- Giữ full end-to-end flow cho nightly run
- Tách smoke regression và full regression
Chạy regression suite trong CI
Regression test chỉ chạy trên laptop của bạn thì chỉ bảo vệ laptop của bạn. Hãy đưa nó vào CI để chạy trên pull request và merge vào nhánh chính.
Mẫu triển khai chung:
- Cài headless runner
- Trỏ runner đến test suite đã lưu
- Chọn environment
- Chạy suite
- Fail build nếu assertion fail
- Xuất report cho CI đọc
Apidog cung cấp CLI runner cho workflow này.
Cài bằng Node:
npm install -g apidog-cli
Chạy một test scenario hoặc test suite bằng ID:
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t 123456 \
-e 789012 \
-r cli,html,junit
Ý nghĩa tham số:
-
--access-token: dùng để xác thực. Lưu trong CI secret, không commit vào repo. -
-t: ID của scenario, folder hoặc test suite cần chạy. -
-e: ID environment, ví dụ staging hoặc production. -
-r: định dạng report.-
cli: in kết quả ra console -
html: tạo report dễ đọc -
junit: xuất XML để CI hiển thị pass/fail theo từng test
-
Ví dụ GitHub Actions chạy 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 }}
Nếu test fail, runner thoát với exit code khác 0, job chuyển đỏ và pull request bị chặn.
Để có pipeline CI/CD đầy đủ hơn, xem Apidog CLI cho CI/CD và cách tự động hóa kiểm thử API trong GitHub Actions.
Nếu suite dùng file dữ liệu, truyền bằng -d:
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t 123456 \
-e 789012 \
-d ./test-data/emails.csv \
-r cli,junit
Nếu muốn chạy test theo branch API riêng, dùng --branch. Nếu muốn lưu lịch sử run trên cloud, thêm --upload-report.
So sánh schema và hợp đồng
Assertion bắt lỗi hồi quy trong runtime behavior. Schema comparison bắt lỗi hồi quy trong định nghĩa API, thường ngay từ pull request.
Workflow nên là:
- OpenAPI spec được version trong repo
- Pull request chỉnh sửa spec
- CI so sánh spec mới với spec trước đó
- Công cụ phân loại thay đổi:
- Non-breaking
- Potentially breaking
- Breaking
- Reviewer thấy rõ thay đổi thay vì đọc một khối YAML lớn
Ví dụ thay đổi an toàn:
Thêm field optional user.avatarUrl
Ví dụ thay đổi gây lỗi:
Xóa user.phone
Đổi user.id từ number sang string
Biến user.email từ optional thành required
Đổi response 200 từ object sang array
Kết hợp schema comparison với contract test trên API thật:
- Spec phát hiện thay đổi có chủ đích trong hợp đồng
- Contract test phát hiện implementation đang lệch khỏi spec
Breaking change không phải lúc nào cũng là bug. Có lúc bạn cố ý xóa field hoặc đổi kiểu dữ liệu. Nhưng thay đổi đó cần đi qua versioning và deprecation, không nên xuất hiện bất ngờ với client.
Xem thêm cách tạo phiên bản và ngừng hỗ trợ API ở quy mô lớn.
Cách Apidog hỗ trợ regression testing
Apidog gom các phần cần thiết vào cùng một workspace:
- Thiết kế API
- Lưu request
- Viết assertion
- Xâu chuỗi scenario
- Gắn dataset CSV/JSON
- Validate response với schema
- Chạy test suite bằng CLI trong CI
Bạn có thể xây dựng scenario trực quan:
- Gửi request tạo resource
- Trích xuất giá trị từ response, ví dụ
body.id - Truyền giá trị đó vào request tiếp theo
- Gắn assertion cho status code, schema và field
- Lưu scenario vào test suite
- Chạy suite bằng
apidog-clitrong CI
Vì API design và test nằm trong cùng một project, bạn có thể validate response với schema đã lưu của endpoint mà không phải định nghĩa schema ở hai nơi.
Với data-driven test, bạn gắn CSV hoặc JSON vào scenario. Apidog chạy một case cho mỗi dòng dữ liệu.
apidog-cli chạy các test suite đã lưu ở chế độ headless. Nó không phải công cụ gửi request tương tác và không phải load generator. Nhiệm vụ của nó là replay regression suite và xuất kết quả để CI quyết định pass/fail.
Xem thêm hướng dẫn pipeline CI/CD của Apidog CLI.
Quy trình bắt đầu trong một buổi chiều
Bạn không cần xây lại toàn bộ chiến lược test. Bắt đầu bằng một workflow nhỏ.
Bước 1: Chọn 5 endpoint có traffic cao nhất
Ưu tiên endpoint có nhiều client gọi:
GET /users/{id}
POST /orders
GET /orders/{id}
POST /payments
POST /auth/login
Rủi ro hồi quy thường tập trung ở nơi có nhiều tích hợp.
Bước 2: Lưu request và thêm assertion
Với mỗi endpoint, thêm assertion tối thiểu:
- Status code
- Response schema
- 2-3 field quan trọng
- Response time nếu cần
Ví dụ:
GET /v1/orders/1001 -> 200
body.id phải tồn tại
body.total kiểu number
body.status thuộc ["created", "paid", "cancelled"]
body.items kiểu array
Bước 3: Thêm một flow có chuỗi request
Chọn resource cốt lõi và test CRUD:
Create -> Read -> Update -> Delete
Flow này bắt lỗi giữa các request mà test endpoint riêng lẻ không thấy.
Bước 4: Thêm dataset cho endpoint có validation phức tạp
Ví dụ với email, amount, coupon code hoặc date range.
amount,expectedStatus
100,201
0,422
-1,422
999999,201
Bước 5: Chạy trong CI trên pull request
Thêm job CI:
npm install -g apidog-cli
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t 123456 \
-e 789012 \
-r cli,junit
Lưu token trong secret:
APIDOG_ACCESS_TOKEN
Nếu test fail, chặn merge.
Bước 6: Mở rộng suite từ lỗi thật
Mỗi bug hồi quy lọt ra production nên trở thành một test case mới.
Quy trình:
Bug xảy ra
-> Viết regression test tái hiện bug
-> Fix bug
-> Test pass
-> Giữ test trong suite
Theo thời gian, suite phản ánh đúng những lỗi mà hệ thống của bạn thực sự dễ mắc.
Câu hỏi thường gặp
Kiểm thử hồi quy API khác gì kiểm thử hồi quy nói chung?
Kiểm thử hồi quy nói chung kiểm lại hành vi toàn hệ thống, gồm UI, business logic và integration. Kiểm thử hồi quy API chỉ tập trung vào HTTP interface: route, status code, response schema và các field quan trọng. Phạm vi hẹp giúp test đủ nhanh để chạy trên mỗi commit.
Nên chạy regression suite bao lâu một lần?
Chạy trên mọi thay đổi có thể ảnh hưởng đến API. Thực tế là:
- Mỗi pull request
- Mỗi merge vào main
- Trước hoặc sau deployment
- Nightly run cho suite lớn hơn
Giữ một core suite nhanh cho pull request và một full suite chậm hơn cho nightly.
Làm sao tránh test dễ vỡ?
Đừng assert dữ liệu không ổn định. Hãy assert contract.
Nên assert:
- Status code
- Field bắt buộc
- Data type
- Enum hợp lệ
- Format như email hoặc date-time
Không nên assert:
- Timestamp cố định
- ID sinh ngẫu nhiên
- Thứ tự array nếu API không cam kết thứ tự
- Error message chi tiết nếu client không phụ thuộc vào nó
Có thể chạy regression test API mà không viết code không?
Có. Công cụ như Apidog cho phép tạo scenario và assertion trực quan, sau đó chạy headless trong CI bằng apidog-cli. Bạn lưu test qua giao diện, còn CLI replay suite trong pipeline.
Xử lý breaking change có chủ đích như thế nào?
Đừng để breaking change xuất hiện như một test failure bất ngờ. Hãy đưa nó qua quy trình versioning và deprecation:
- Gắn cờ thay đổi bằng schema comparison
- Thông báo cho consumer
- Thêm version mới hoặc field thay thế
- Duy trì field cũ trong thời gian chuyển tiếp
- Cập nhật regression baseline sau khi thay đổi được chấp nhận
Mục tiêu không phải là cấm mọi breaking change. Mục tiêu là làm cho chúng rõ ràng, được review và được triển khai có kiểm soát.
Top comments (0)