Postman và kiểm thử API trong phỏng vấn QA: cần biết gì và luyện thế nào
Câu hỏi về Postman nhanh chóng cho thấy bạn chỉ biết thuật ngữ API hay thật sự biết gửi request và đọc response.
- Method và URL
- Auth và headers
- Body và params
- Status, schema và dữ liệu
Cần làm được gì trong Postman
Tạo request, chọn GET/POST, thêm query params, gửi JSON body, thêm Authorization header và đọc status code cùng response body.
Điều này quan trọng hơn automation nâng cao trong phỏng vấn junior.
Những kiểm tra được mong đợi
Mỗi API response có bốn lớp: status code, cấu trúc, giá trị và side effect.
- Status code đúng tình huống.
- Field bắt buộc tồn tại và đúng kiểu.
- Giá trị quan trọng khớp yêu cầu.
- Lỗi không lộ stack trace.
- Request lặp lại không tạo bản sao ngoài ý muốn.
Kiểm auth trong API
Gửi request với token đúng, không token, token sai và token của người dùng khác.
Nếu endpoint trả dữ liệu, hãy hỏi: đây là dữ liệu của ai?
Lỗi thường gặp khi dùng Postman ở phỏng vấn
Chỉ gửi happy path, thấy 200 là dừng, quên headers và không lưu lại request đã tái hiện lỗi.
Sau response đáng ngờ, ghi ngay method, path, body và response.
Bài luyện trước phỏng vấn
Kiểm một endpoint với dữ liệu đúng, thiếu field bắt buộc, sai kiểu, giá trị biên, không token và id của object người khác.
Nếu bạn giải thích được expected response và viết một bug report, bạn đã sẵn sàng cho phần lớn câu hỏi junior về Postman.
Assertion thật trong tab Tests
Mỗi test nên nói rõ promise nào đang được bảo vệ. Assertion riêng giúp định vị lỗi nhanh hơn một block lớn. Kiểm status và response type trước, rồi schema, business value, cuối cùng mới lưu id cho request sau.
Script dưới đây chưa chứng minh toàn bộ order đúng, nhưng tạo signal tối thiểu tốt: JSON đọc được, field bắt buộc đúng type, total dương và id có thể dùng tiếp.
pm.test("order created", () => pm.response.to.have.status(201));\n\nconst body = pm.response.json();\npm.test("contract and values", () => {\n pm.expect(body).to.have.property("id").that.is.a("number");\n pm.expect(body).to.have.property("status", "new");\n pm.expect(body.total).to.be.a("number").and.above(0);\n});\n\npm.collectionVariables.set("orderId", body.id);
Variable, chaining, Runner và CI
Dùng scope nhỏ nhất: local cho secret tạm, data variable cho một row Runner, environment cho host, collection cho scenario data. Không commit token thật trong collection export. Đánh dấu record test bằng prefix riêng và cleanup nếu được phép.
- Pre-request script tạo data unique hoặc refresh token.
- Tests chỉ lưu response id sau khi contract đã pass.
- Request sau dùng {{orderId}} và kiểm đúng object đó.
- Collection Runner lặp flow bằng CSV/JSON, gồm cả negative row.
- Postman CLI hoặc Newman chạy collection trong CI và trả exit code khác 0 khi fail.
Câu hỏi đào sâu trong phỏng vấn
Hãy giải thích vì sao chỉ kiểm 200 là yếu, secret nên lưu đâu, 401 khác 403 thế nào, điều gì xảy ra khi retry POST sau timeout và cách kiểm pagination, rate limit, object id của user khác.
Ứng viên mạnh nêu test oracle: OpenAPI, acceptance criterion, RFC, GET tiếp theo, database state hoặc business rule đã thống nhất. Không có oracle, script đẹp chỉ đóng băng behaviour hiện tại.
Ví dụ thực tế: order tạo thành công nhưng tổng tiền sai
Thay vì nhiều request rời rạc, hãy dựng một chuỗi có thể tái hiện: đăng nhập, đọc catalog, thêm hàng, áp promo, tạo order rồi đọc lại. Mỗi bước cần oracle độc lập, không chỉ HTTP status.
- Tạo dữ liệu độc lập và xác thực.
- Đọc giá và lưu product_id.
- Tạo order và tính total mong đợi.
- Đọc lại order và kiểm tác dụng phụ.
Làm rõ môi trường và dữ liệu
Đặt base_url và token test trong environment nhưng không đăng secret cùng collection. Lấy product_id từ response catalog thay vì dùng id cũ tùy ý. Mỗi lần chạy nên có cart và user riêng; account dùng chung khiến test ảnh hưởng nhau. Ghi giá trị nào lấy động từ response và giá trị nào cố định theo contract.
Kiểm giá trị chứ không chỉ schema
Schema chỉ chứng minh total là số, không chứng minh nó đúng. Hai cuốn sách giá 690 RUB, giảm 10% thì total là 1.242 RUB nếu cả hai được giảm và rule làm tròn đã thống nhất. So giá catalog, từng dòng order, discount, total và currency. Nếu công thức hoặc thứ tự áp giảm giá chưa có trong tài liệu, hãy làm rõ contract thay vì lấy response hiện tại làm đáp án.
Đọc lại sau khi ghi
POST có thể trả 201 với JSON hợp lý nhưng order lưu lại có tổng tiền khác. Gọi GET /orders/{id}; nếu được phép, kiểm dữ liệu lưu và số lần trừ tiền. Với operation được quy định idempotent, gửi lại cùng key và đảm bảo không tạo order thứ hai. Đừng mặc định mọi POST đều có bảo đảm này: đó là thuộc tính của contract cụ thể.
Làm cho lỗi dễ chẩn đoán
Assertion nên nói `expected_total=1242, actual_total=1380` thay vì chỉ “test failed”. Nhóm request theo scenario và dọn dữ liệu bằng cách đã thỏa thuận. Trong CI dùng environment riêng và lưu report; phân biệt token hết hạn hay shared state với lỗi thật của sản phẩm.
const body = pm.response.json();\npm.test("created order has the agreed total", () => {\n pm.response.to.have.status(201);\n pm.expect(body.currency).to.eql("RUB");\n pm.expect(body.total).to.eql(1242);\n});\npm.environment.set("order_id", body.id);\n// Next: GET /orders/{{order_id}} and compare persisted total.
Bug thực sự nằm ở đâu?
201 với total 1380 thay vì 1242 theo rule đã chốt là lỗi chức năng dù schema pass. Nếu POST trả 1242 nhưng GET trả 1380, nghi vấn thuộc lưu hoặc đọc dữ liệu. Nếu cả hai đều 1242 mà số tiền bị trừ là 1380, lỗi ở đoạn sau của flow. Phân biệt như vậy quan trọng hơn tên công cụ.
Tình huống thứ hai: request lỗi và tương thích phiên bản API
Happy path vẫn chạy. Server mới yêu cầu `delivery_address` trong POST /orders nhưng mobile client cũ không gửi field này. Đây vừa là kiểm validation vừa là kiểm tương thích khi server và ứng dụng được phát hành vào các thời điểm khác nhau.
Lập ma trận phiên bản
Client cũ với server cũ là mốc so sánh. Client cũ với server mới là rủi ro chính khi deploy backend. Client mới với server cũ cũng quan trọng nếu rollback backend. Client mới với server mới là trạng thái bình thường. Hỏi team phiên bản nào còn được hỗ trợ và đến khi nào trước khi bỏ một dòng khỏi ma trận.
Phân biệt validation và tương thích
Với client mới, kiểm field bị thiếu, null, rỗng, toàn khoảng trắng, quá dài và sai kiểu. Nhưng client cũ không biết field này có thể nhận 422 sau deploy: đó là regression dù schema mới hợp lệ. Team có thể tạm cho field optional hoặc lấy địa chỉ đã lưu; QA nêu rõ xung đột để product chọn chính sách.
Kiểm tác dụng phụ của request bị từ chối
Nếu contract hứa atomicity, 422 không được tạo order, giữ tồn kho hay trừ tiền. Sửa địa chỉ rồi retry để phát hiện order dở dang. 400 thay vì 422 không tự động là bug: status và cấu trúc lỗi phải theo API contract. Response nên chỉ rõ field cần sửa mà không lộ thông tin nhạy cảm.
Theo dữ liệu qua các lớp
POST có thể trả đúng địa chỉ mới nhưng order lưu địa chỉ cũ từ profile. Đọc lại order, kiểm UI và event gửi tới dịch vụ giao hàng. Một bản sao sai đôi khi chỉ xuất hiện sau thanh toán. Dùng correlation id để đối chiếu thay vì kết luận từ một response.
Bảo vệ consumer cũ bằng contract test
Giữ request thật từ phiên bản còn hỗ trợ trong collection hoặc consumer-driven contract. CI cần chứng minh server mới chấp nhận payload cũ và giữ các field app cũ dùng. JSON Schema kiểm cấu trúc nhưng không diễn tả đầy đủ ý nghĩa business của optional hay default; ghi quyết định đó riêng.
Client v1 + Server v1: baseline\nClient v1 + Server v2: missing address; follow support policy\nClient v2 + Server v1: rollback; unknown field handling\nClient v2 + Server v2: valid, missing, null, empty, wrong type\nRejected requests: no order, reservation or charge
Kết quả investigation là gì?
Một ma trận phiên bản được hỗ trợ, request thực của app cũ, error contract đã thống nhất và bằng chứng request lỗi không có tác dụng phụ. Nhờ vậy team chọn thứ tự rollout và ngày dừng hỗ trợ, còn QA có case tái hiện được.
Câu hỏi thường gặp về Postman
Manual QA có cần học JavaScript cho phỏng vấn không?
Thường chỉ cần đọc JSON, khai báo const, truy cập field và viết pm.test với pm.expect. Giải thích assertion bảo vệ gì quan trọng hơn. Vị trí cụ thể có thể yêu cầu cao hơn.
Postman có thay thế kiểm database không?
Không. API cho external contract. Side effect quan trọng có thể cần GET tiếp theo, event, database record hoặc integration check.
Collection Runner khác Newman hoặc Postman CLI thế nào?
Runner chạy tương tác trong Postman. CLI chạy collection trong terminal và CI, nơi environment, reporter và exit code quan trọng. Assertion nên giữ nguyên.
Postman không phải mục tiêu. Mục tiêu là thấy server đã hứa gì và thật sự làm gì.