Phạm vi an toàn: Áp dụng cho môi trường QA, staging hoặc pre-production mà bạn sở hữu hoặc được uỷ quyền kiểm thử — không dùng cho hệ thống bên thứ ba hay luồng chưa được cho phép.
Một luồng đăng ký hay checkout hiếm khi chỉ gặp một CAPTCHA — widget có thể xuất hiện ở bước xác minh rồi lại ở bước thanh toán. Giải từng widget rời rạc khiến token hết hạn giữa hai bước và log không nối được với nhau. Bài này trình bày cách điều phối CaptchaAI qua nhiều bước QA, vẫn giữ idempotency khi retry và truy vết đầy đủ khi debug.
Vì sao một luồng QA có nhiều bước CAPTCHA
Đội QA tại công ty outsourcing hay in-house ở Việt Nam thường kiểm thử luồng nhiều bước cho khách hàng quốc tế: đăng ký, xác minh, rồi checkout — mỗi bước có thể gắn một widget khác nhau, ví dụ reCAPTCHA v2 và Turnstile. Coi mỗi bước là kịch bản độc lập khiến CI báo đỏ mà không rõ bước nào gây lỗi.
Thiết kế luồng CAPTCHA nhiều bước với qa_case và step_id
- Gắn mỗi lần chạy với một
qa_case— định danh cho cả kịch bản. - Gắn mỗi bước bên trong với một
step_idriêng. - Chỉ gọi CaptchaAI khi widget thực sự xuất hiện; gọi "phòng hờ" trước đó vừa tốn thread vừa làm nhiễu log.
Giữ idempotency khi retry giữa các bước
Luồng nhiều bước retry nhiều hơn luồng một bước vì bất kỳ bước giữa nào cũng có thể timeout. Token CaptchaAI trả về vẫn hợp lệ trong một khoảng ngắn — khi retry cùng step_id, tái sử dụng token cũ nếu còn hạn thay vì gọi lại từ đầu, giữ mức dùng thread ổn định trong gói bạn đang chạy, dù là BASIC ($15/tháng, 5 thread) hay ADVANCE ($90/tháng, 50 thread).
Theo dõi từng bước bằng correlation id
Ghi log có cấu trúc, không phải văn bản tự do: tối thiểu gồm qa_case, step_id, thời gian lấy token, mã trạng thái HTTP và ID task. Nối các bước trong cùng kịch bản bằng một correlation id — OpenTelemetry là lựa chọn hợp lý nếu team đã dùng — để phát lại toàn bộ luồng từ một id duy nhất khi debug. Nếu log chứa dữ liệu cá nhân của tài khoản test, chỉ lưu mã trạng thái thay vì nguyên văn payload, theo tinh thần Nghị định 13/2023/NĐ-CP.
Khắc phục sự cố thường gặp
| Vấn đề | Nguyên nhân | Cách xử lý |
|---|---|---|
| Test không tìm thấy widget | Selector hoặc thời điểm load đổi | Kiểm tra wait_for_selector trên staging |
ERROR_NO_SLOT_AVAILABLE |
Hàng đợi đầy tạm thời | Retry với backoff, đừng tăng max_workers để bù |
| Backend từ chối token | Sai action, sitekey hoặc secret | Đối chiếu cấu hình từng bước với staging |
Danh mục kiểm tra trước khi đưa vào CI
- Phạm vi kiểm thử giới hạn trong tài nguyên đã uỷ quyền.
- API key nằm trong CI secret hoặc vault, không trong mã nguồn.
- Mỗi lần chạy ghi thời gian gọi, mã trạng thái và
step_id. - Có chính sách retry idempotent với giới hạn số lần.
Ví dụ gọi CaptchaAI trong một bước QA
Đoạn Python dưới đây minh hoạ luồng tối thiểu: gửi task rồi polling kết quả trên staging.
import os
import requests
API_KEY = os.environ['CAPTCHAAI_KEY']
QA_PAGE_URL = os.environ['QA_PAGE_URL'] # ví dụ https://staging.example.com/qa-login
QA_SITE_KEY = os.environ['QA_SITE_KEY']
def submit_qa_recaptcha() -> str:
payload = {
'clientKey': API_KEY,
'task': {
'type': 'NoCaptchaTaskProxyless',
'websiteURL': QA_PAGE_URL,
'websiteKey': QA_SITE_KEY,
},
}
response = requests.post(
'https://api.captchaai.com/createTask',
json=payload,
timeout=30,
)
response.raise_for_status()
return response.json()['taskId']
def fetch_qa_result(task_id: str) -> dict:
payload = {'clientKey': API_KEY, 'taskId': task_id}
response = requests.post(
'https://api.captchaai.com/getTaskResult',
json=payload,
timeout=30,
)
response.raise_for_status()
return response.json()
Câu hỏi thường gặp
Luồng QA nhiều bước này có chạm vào lưu lượng production không?
Không. Mọi ví dụ giả định môi trường được uỷ quyền như staging.example.com — không chạy trực tiếp trên production.
Nên dùng polling hay callback cho một kịch bản nhiều bước?
Polling đơn giản hơn và đủ cho phần lớn pipeline CI. Cân nhắc callback khi kịch bản có trên 5-6 bước CAPTCHA liên tiếp.
Có thể đặt API key trực tiếp trong mã không?
Không. Nạp khoá qua trình quản lý secret của CI hoặc vault; khoá đã lỡ commit phải xoay vòng ngay, kể cả trên nhánh test.
Retry bao nhiêu lần là hợp lý giữa các bước?
Ba lần với backoff luỹ thừa (1s, 2s, 4s) là điểm khởi đầu hợp lý. Lỗi mạng, mã 5xx và ERROR_NO_SLOT_AVAILABLE đáng để retry; lỗi xác thực kéo dài thì nên dừng ngay.
Tài liệu liên quan an toàn
- Bắt đầu nhanh với CaptchaAI
- Kiểm thử CAPTCHA được uỷ quyền
- Kiểm thử endpoint CAPTCHA trên biểu mẫu
- Test trình duyệt fail nhưng API chạy: gỡ lỗi
- Giải reCAPTCHA v2 qua API
- Giải Cloudflare Turnstile qua API
- Giải GeeTest v3 qua API
Kiểm thử luồng CAPTCHA nhiều bước với CaptchaAI.