Anwendungsfälle

CAPTCHA-Lösung für Qualitätssicherung und autorisierte Tests

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:

  1. Übermitteln: Sie senden Sitekey und Page-URL an den Endpunkt in.php und erhalten eine Task-ID zurück.
  2. Abfragen (Polling): Sie fragen res.php in kurzen Abständen ab, bis das Token bereitsteht – für reCAPTCHA v2 dauert das in der Regel einige Sekunden.
  3. Einfügen: Sie tragen das Token in das Feld g-recaptcha-response ein 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


Automatisieren Sie Ihre QA-Pipeline – binden Sie CaptchaAI in Ihre Tests ein.

Kommentare sind für diesen Artikel deaktiviert.