Phạm vi an toàn: Chỉ á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 — không dành cho hệ thống bên thứ ba.
Trang kết quả tìm kiếm là màn hình khó giữ trong bộ test nhất: widget CAPTCHA bật lên là snapshot kết quả hết so sánh được. Tắt widget trên staging là cách nhanh gọn, và cũng là cách bỏ phần dễ hỏng nhất khỏi vùng kiểm thử. Hướng đúng là cho test đi trọn luồng: dựng dữ liệu giả lập, lấy token qua CaptchaAI, rồi kiểm tra backend có xác thực token.
Bốn lớp cần phủ khi trang kết quả có CAPTCHA
| Lớp kiểm thử | Câu hỏi cần trả lời | Tín hiệu pass |
|---|---|---|
| Giao diện | Widget render đúng selector? | wait_for_selector trả về trước timeout |
| Lấy token | Token về sau bao lâu? | Token hợp lệ trước 120 giây |
| Backend | Có gọi bước verify? | Request thiếu token bị 4xx |
| Kết quả | Thứ tự kết quả ổn định? | Snapshot khớp fixture |
Dữ liệu giả lập cho trang kết quả
Sinh truy vấn và bản ghi tổng hợp trong staging, đừng chép dữ liệu production sang. Fixture đủ dùng gồm:
- Truy vấn có kết quả, truy vấn rỗng, và truy vấn có dấu tiếng Việt (
điện thoại,Đà Nẵng) để bắt lỗi encoding. - Đủ bản ghi cho ba trang phân trang, ID và tên ngẫu nhiên.
Ví dụ: đội QA sàn thương mại điện tử tại TP.HCM
Một đội QA vận hành sàn nội địa bật reCAPTCHA v3 trên ô tìm kiếm, và bộ hồi quy hằng đêm đỏ hàng loạt. Họ cấp sitekey riêng cho staging, cho bộ test lấy token qua CaptchaAI như phiên người dùng thật, rồi thêm một test khẳng định request không kèm token phải bị chặn — lớp bảo vệ vừa bật vẫn nằm trong vùng kiểm thử.
Lấy token bằng CaptchaAI trong CI
Luồng tối thiểu: gửi task kèm websiteURL và websiteKey của staging, nhận taskId, rồi polling kết quả.
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()
Gọi fetch_qa_result mỗi vài giây cho tới khi có token rồi submit ngay: token reCAPTCHA chỉ sống khoảng 120 giây, đừng để nó chờ qua stage khác.
Kiểm tra backend có xác thực token
- Request hợp lệ kèm token phải trả về đúng tập kết quả giả lập.
- Gửi lại token đó lần hai phải bị từ chối, vì token chỉ dùng một lần.
- Request không có token phải nhận 4xx, không được bỏ qua bước verify.
Bước thứ ba hay bị bỏ sót nhất: đó là kiểu sai cấu hình khiến widget trông vẫn chạy còn server không kiểm tra gì.
Log và danh mục kiểm tra trước khi merge
- Ghi thời gian lấy token, mã trạng thái HTTP, ID task và một correlation id chung cho cả lượt chạy.
- API key nằm trong CI secret hoặc vault, không nằm trong mã nguồn; khoá lỡ commit thì xoay vòng ngay.
- Thử lại idempotent, có giới hạn trên cho lỗi tạm thời.
Khắc phục sự cố thường gặp
| Vấn đề | Nguyên nhân thường gặp | Cách xử lý |
|---|---|---|
| Test không thấy widget | Selector đổi hoặc load trễ | Nới wait_for_selector |
ERROR_NO_SLOT_AVAILABLE |
Hết thread rảnh lúc gửi task | Thử lại với backoff 1s, 2s, 4s |
| Backend từ chối token | Lệch action, sitekey hoặc secret | Đối chiếu cấu hình hai môi trường |
Câu hỏi thường gặp
CaptchaAI có hỗ trợ hCaptcha không?
Không. Danh sách hỗ trợ gồm reCAPTCHA v2/v3 và Enterprise, Cloudflare Turnstile và Challenge, GeeTest v3, CAPTCHA ảnh/OCR, grid image, BLS; CaptchaFox, Friendly Captcha, Lemin ở beta. FunCaptcha (Arkose Labs) chưa được hỗ trợ, GeeTest v4 sắp ra mắt.
Pipeline CI cần bao nhiêu thread?
Đếm số job song song có bước CAPTCHA, không phải tổng số test. BASIC ($15/tháng, 5 thread) đủ cho pipeline nhỏ; nhiều repo bắn hồi quy cùng khung giờ thì STANDARD ($30/tháng, 15 thread) an toàn hơn. CaptchaAI tính giá theo thread, không theo lượt giải.
Dữ liệu giả lập có cần tuân thủ quy định dữ liệu cá nhân?
Có, nếu bạn chép dữ liệu thật sang staging. Nghị định 13/2023/NĐ-CP là lý do thực tế để sinh dữ liệu tổng hợp và chỉ giữ ID task, mã trạng thái trong log.
Đọc thêm
- Bắt đầu nhanh với CaptchaAI
- Kiểm thử CAPTCHA được uỷ quyền
- Kiểm thử endpoint CAPTCHA trên form
- Test trình duyệt đỏ, API vẫn xanh
- Giải reCAPTCHA v2 qua API
- Giải Cloudflare Turnstile qua API
- Giải GeeTest v3 qua API
Kiểm thử tích hợp CAPTCHA của bạn trên staging với CaptchaAI.