测试团队需要定期验证受验证码保护的流程。 CaptchaAI 可让您自动执行这些测试,而无需手动验证码交互。
当 QA 团队需要验证码解决时
| 设想 | 为什么 CaptchaAI 有帮助 |
|---|---|
| 回归测试 | 验证表单在部署后仍然有效 |
| 端到端测试 | 测试完整的用户旅程 |
| 负载测试 | 大规模模拟真实的验证码流 |
| 跨浏览器测试 | 验证跨浏览器的验证码呈现 |
| 辅助功能测试 | 测试残疾用户的替代流程 |
Pytest 集成
import pytest
import requests
import time
class CaptchaTestHelper:
"""Helper for solving CAPTCHAs in test environments."""
def __init__(self, api_key):
self.api_key = api_key
def solve_recaptcha(self, sitekey, pageurl, timeout=120):
"""Solve reCAPTCHA and return token."""
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": self.api_key,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": 1,
}, timeout=30)
result = resp.json()
assert result.get("status") == 1, f"Submit failed: {result}"
task_id = result["request"]
deadline = time.time() + timeout
time.sleep(10)
while time.time() < deadline:
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": self.api_key, "action": "get",
"id": task_id, "json": 1,
}, timeout=15)
data = resp.json()
if data.get("status") == 1:
return data["request"]
if data["request"] != "CAPCHA_NOT_READY":
raise RuntimeError(f"Solve error: {data['request']}")
time.sleep(5)
raise TimeoutError("CAPTCHA solve timeout")
@pytest.fixture(scope="session")
def captcha_helper():
"""Provide CaptchaAI helper for test session."""
import os
api_key = os.environ.get("CAPTCHAAI_API_KEY")
if not api_key:
pytest.skip("CAPTCHAAI_API_KEY not set")
return CaptchaTestHelper(api_key)
class TestLoginFlow:
"""Test login flow behind reCAPTCHA."""
SITEKEY = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
LOGIN_URL = "https://staging.staging.example.com/qa-login"
def test_login_with_valid_credentials(self, captcha_helper):
"""Verify login succeeds with valid creds and solved CAPTCHA."""
token = captcha_helper.solve_recaptcha(self.SITEKEY, self.LOGIN_URL)
assert token and len(token) > 100
resp = requests.post(self.LOGIN_URL, data={
"username": "test_user",
"password": "test_pass",
"g-recaptcha-response": token,
})
assert resp.status_code == 200
assert "Welcome" in resp.text
def test_login_with_invalid_credentials(self, captcha_helper):
"""Verify login fails gracefully with bad creds but valid CAPTCHA."""
token = captcha_helper.solve_recaptcha(self.SITEKEY, self.LOGIN_URL)
resp = requests.post(self.LOGIN_URL, data={
"username": "wrong_user",
"password": "wrong_pass",
"g-recaptcha-response": token,
})
assert resp.status_code in (200, 401)
assert "Invalid" in resp.text or "error" in resp.text.lower()
def test_login_without_captcha_fails(self):
"""Verify login rejects submissions without CAPTCHA."""
resp = requests.post(self.LOGIN_URL, data={
"username": "test_user",
"password": "test_pass",
})
assert resp.status_code in (400, 403, 422)
Selenium E2E 测试模式
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
@pytest.fixture
def browser():
"""Create browser for testing."""
options = webdriver.ChromeOptions()
options.add_argument("--window-size=1920,1080")
driver = webdriver.Chrome(options=options)
yield driver
driver.quit()
class TestRegistrationFlow:
"""Test registration form with CAPTCHA."""
REG_URL = "https://staging.example.com/register"
def test_registration_form_submits(self, browser, captcha_helper):
"""Full registration flow with CAPTCHA solving."""
browser.get(self.REG_URL)
# Fill form
browser.find_element(By.ID, "email").send_keys("test@example.com")
browser.find_element(By.ID, "password").send_keys("SecurePass123!")
browser.find_element(By.ID, "confirm_password").send_keys("SecurePass123!")
# Extract sitekey from page
captcha_div = browser.find_element(By.CSS_SELECTOR, ".g-recaptcha")
sitekey = captcha_div.get_attribute("data-sitekey")
# Solve via API
token = captcha_helper.solve_recaptcha(sitekey, browser.current_url)
# Inject token
browser.execute_script("""
document.querySelector('[name="g-recaptcha-response"]').value = arguments[0];
""", token)
# Trigger callback if needed
callback = captcha_div.get_attribute("data-callback")
if callback:
browser.execute_script(f"window['{callback}'](arguments[0]);", token)
# Submit
browser.find_element(By.CSS_SELECTOR, "button[type=submit]").click()
# Verify success
WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".success-message"))
)
def test_captcha_renders_on_page(self, browser):
"""Verify CAPTCHA widget loads on registration page."""
browser.get(self.REG_URL)
captcha = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".g-recaptcha, iframe[src*='recaptcha']"))
)
assert captcha.is_displayed()
测试配置
# conftest.py
import os
# Mark tests that need CAPTCHA solving
def pytest_configure(config):
config.addinivalue_line(
"markers", "captcha: tests requiring CAPTCHA solving (may be slow)"
)
# pytest.ini or pyproject.toml
"""
[tool.pytest.ini_options]
markers = [
"captcha: tests requiring CAPTCHA solving (may be slow)",
]
"""
仅运行验证码测试:
pytest -m captcha -v
无需验证码测试即可运行(快速管道):
pytest -m "not captcha" -v
具有成本效益的测试技巧
| 战略 | 益处 |
|---|---|
| 使用暂存环境 | 较低的验证码难度 |
| 按计划运行验证码测试,而不是每次推送 | 降低 API 成本 |
| 缓存片状测试的测试结果 | 避免不必要的重新解决 |
| 使用环境标志在本地跳过验证码 | 节省开发成本 |
| 在专用 CI 作业中进行批量验证码测试 | 控制每条管道的成本 |
常问问题
运行验证码测试需要多少费用?
每个 reCAPTCHA v2 解决成本约为 0.003 美元。包含 50 个 CAPTCHA 测试的测试套件每次运行成本约为 0.15 美元。每日运行成本 ~$4.50/month.
我应该在单元测试中解决验证码吗?
不。在单元测试中模拟验证码响应。仅在针对真实环境的集成和端到端测试中解决真实的验证码。
我可以将 CaptchaAI 与其他测试框架一起使用吗?
是的。 CaptchaAI 基于 HTTP,因此它可以与任何语言的任何测试框架配合使用 - Jest、Mocha、JUnit、NUnit 等。
相关指南
- 道德验证码解决指南
- GitHub 操作 CI/CD 验证码测试
自动化您的 QA 流程 –将 CaptchaAI 添加到您的测试中.