CAPTCHA-geschützte Logins, Registrierungen und Checkout-Formulare lassen sich vollständig automatisiert testen: CaptchaAI löst die Abfrage per API, Ihre Test-Suite fügt das zurückgegebene Token ein und läuft ohne manuellen Klick weiter. So bleibt jeder reCAPTCHA-geschützte Ablauf Teil Ihrer Regressions- und E2E-Tests, statt bei jedem Durchlauf an einer Sicherheitsabfrage hängenzubleiben.
Der Ansatz gilt ausschließlich für Anwendungen, die Sie selbst betreiben oder für die Sie eine ausdrückliche Testfreigabe haben – Staging-Umgebungen, eigene Formulare, interne Portale. Genau darum geht es bei „autorisierten Tests": Sie prüfen Ihre eigene Absicherung, nicht die einer fremden Seite.
Wann QA-Teams eine CAPTCHA-Lösung brauchen
Sobald ein kritischer Ablauf hinter einem CAPTCHA liegt, blockiert die Abfrage jede automatisierte Prüfung. Diese Szenarien profitieren am deutlichsten:
| Szenario | Wozu CaptchaAI beiträgt |
|---|---|
| Regressionstests | Prüfen, ob Formulare nach jedem Deploy noch abschickbar sind |
| End-to-End-Tests | Komplette User Journeys inklusive Anmeldung durchspielen |
| Lasttests | Realistische CAPTCHA-Abläufe im großen Maßstab simulieren |
| Cross-Browser-Tests | Sicherstellen, dass das CAPTCHA-Widget in jedem Browser rendert |
| Barrierefreiheits-Tests | Alternative Abläufe für Nutzer mit assistiven Technologien prüfen |
So läuft eine CAPTCHA-Lösung im Test ab
Der Ablauf ist bei jedem Test-Framework identisch und besteht aus drei Schritten:
- Übermitteln: Sie senden Sitekey und Page-URL an den Endpunkt
in.phpund erhalten eine Task-ID zurück. - Abfragen (Polling): Sie fragen
res.phpin kurzen Abständen ab, bis das Token bereitsteht – für reCAPTCHA v2 dauert das in der Regel einige Sekunden. - Einfügen: Sie tragen das Token in das Feld
g-recaptcha-responseein und senden das Formular ab.
Weil dieser Ablauf rein HTTP-basiert ist, brauchen Sie keine zusätzliche Browser-Erweiterung und keine Änderung an der zu testenden Anwendung. Ein kleiner Helper kapselt Übermittlung und Polling, sodass jeder Test nur noch eine Zeile aufruft.
Pytest-Integration
Ein wiederverwendbarer Helper und eine Session-Fixture halten den API-Schlüssel aus dem Testcode heraus. Der Login-Test deckt bewusst drei Fälle ab: gültige Anmeldedaten mit gelöstem CAPTCHA, ungültige Daten und eine Übermittlung ganz ohne Token – so verifizieren Sie sowohl den Erfolgspfad als auch die Abwehr fehlerhafter Anfragen.
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.example.com/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)
Die Session-Fixture überspringt CAPTCHA-Tests automatisch, wenn CAPTCHAAI_API_KEY nicht gesetzt ist. So bleibt die Suite auch auf Rechnern ohne Schlüssel lauffähig, statt mit einem Fehler abzubrechen.
Selenium-Muster für End-to-End-Tests
Bei echten End-to-End-Tests im Browser lesen Sie den Sitekey direkt aus dem DOM, lösen ihn per API und schreiben das Token ins versteckte Feld. Falls das Widget einen Callback erwartet, lösen Sie ihn nach dem Einfügen manuell aus – sonst bemerkt das Formular das Token nicht.
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()
Der zweite Test prüft nur, ob das Widget überhaupt rendert – ein günstiger Smoke-Test ohne API-Aufruf, der schon einen kaputten CAPTCHA-Einbau nach einem Deploy auffängt.
Testkonfiguration und Marker
Trennen Sie langsame CAPTCHA-Tests per Pytest-Marker vom Rest der Suite. So läuft Ihre schnelle Pipeline bei jedem Push, während die kostenpflichtigen Tests nur dann anlaufen, wenn Sie es ausdrücklich wollen.
# 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)",
]
"""
Nur die CAPTCHA-Tests ausführen:
pytest -m captcha -v
Ohne CAPTCHA-Tests ausführen (schnelle Pipeline):
pytest -m "not captcha" -v
In GitLab CI oder GitHub Actions bietet sich derselbe Schnitt an: Der reguläre Job läuft mit -m "not captcha" bei jedem Commit, ein separater, geplanter Job (-m captcha) prüft nachts oder vor dem Release die CAPTCHA-geschützten Abläufe.
Kosten im Griff behalten
CaptchaAI rechnet Thread-basiert ab, nicht pro Lösung: Sie zahlen pro gleichzeitigem Thread und lösen damit unbegrenzt viele CAPTCHAs im Abrechnungsmonat. Für eine typische QA-Pipeline genügt der Einstiegstarif BASIC (15 $/Monat, 5 Threads). Erst wenn Lasttests viele Abfragen parallel auslösen, lohnen größere Tarife wie STANDARD (30 $/Monat, 15 Threads) oder ADVANCE (90 $/Monat, 50 Threads). Die Preise sind in US-Dollar angegeben.
Weil jeder Aufruf trotzdem Threads bindet und Laufzeit kostet, sparen diese Strategien spürbar:
| Strategie | Vorteil |
|---|---|
| Gegen eine Staging-Umgebung testen | Meist niedrigerer CAPTCHA-Schwierigkeitsgrad |
| CAPTCHA-Tests nach Zeitplan statt bei jedem Push | Weniger API-Aufrufe, geringere Kosten |
| Ergebnisse instabiler (flaky) Tests zwischenspeichern | Unnötige Neulösungen vermeiden |
| CAPTCHAs lokal per Umgebungsvariable überspringen | Kosten während der Entwicklung sparen |
| CAPTCHA-Tests in einem dedizierten CI-Job bündeln | Kosten pro Pipeline steuern |
Autorisierte Tests: den Rahmen wahren
Testen Sie nur Anwendungen, die Sie selbst betreiben oder für die eine schriftliche Freigabe vorliegt. Für DACH-Teams bedeutet das in der Praxis:
- Eigene Umgebungen zuerst: CAPTCHA-Automatisierung gehört in Staging-Umgebungen und interne Portale, nicht auf fremde Produktivseiten.
- DSGVO mitdenken: Sobald Testdaten personenbezogene Merkmale enthalten – etwa echte E-Mail-Adressen oder IP-Adressen – prüfen Sie die Rechtsgrundlage und weichen Sie auf synthetische Testdatensätze aus.
- Freigabe dokumentieren: Testen Sie im Auftrag Dritter, halten Sie den Umfang der Erlaubnis schriftlich fest.
Diese Klarheit ist kein Beiwerk, sondern die Bedingung dafür, dass automatisiertes CAPTCHA-Lösen in Ihrer QA überhaupt sauber einsetzbar ist.
Häufige Fragen
Ist automatisiertes CAPTCHA-Lösen in eigenen Tests erlaubt?
Ja, solange Sie die getestete Anwendung selbst betreiben oder eine ausdrückliche Testfreigabe haben. Beschränken Sie sich auf eigene Staging-Umgebungen und interne Formulare; fremde Produktivseiten ohne Erlaubnis sind tabu.
Wie viel kostet eine CAPTCHA-Test-Suite pro Monat?
Nichts pro einzelner Lösung – CaptchaAI rechnet Thread-basiert ab. Der BASIC-Tarif (15 $/Monat, 5 Threads) deckt eine typische QA-Suite mit unbegrenzten Lösungen vollständig ab; erst hoch parallelisierte Lasttests erfordern einen größeren Tarif.
Wie verhindere ich, dass CAPTCHA-Tests meine Pipeline verlangsamen?
Trennen Sie sie per Pytest-Marker (-m captcha) vom schnellen Testlauf und starten Sie sie in einem separaten, geplanten CI-Job – etwa nachts oder vor jedem Release statt bei jedem Push.
Funktioniert CaptchaAI mit GitLab CI und GitHub Actions?
Ja. Die Integration ist rein HTTP-basiert und damit von jedem Test-Framework und jeder CI-Plattform aus nutzbar – GitLab CI, GitHub Actions, Jenkins, Jest, JUnit, NUnit und weitere.
Verwandte Leitfäden
- CAPTCHA-Handling in CI/CD-Pipelines
- CAPTCHA-Tests mit GitHub Actions automatisieren
Automatisieren Sie Ihre QA-Pipeline – binden Sie CaptchaAI in Ihre Tests ein.