DevOps & Mise à l'Échelle

Actions GitHub + CaptchaAI : test CAPTCHA CI/CD

Les pages protégées par CAPTCHA interrompent les tests automatisés. CaptchaAI s'intègre à GitHub Actions pour résoudre les CAPTCHA pendant les tests CI/CD, gardant ainsi votre pipeline vert.


Flux de travail des actions GitHub

# .github/workflows/captcha-tests.yml
name: CAPTCHA Integration Tests

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:

    - cron: "0 6 * * 1"  # Weekly Monday 6 AM

jobs:
  captcha-tests:
    runs-on: ubuntu-latest
    timeout-minutes: 15

    steps:

      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"

      - name: Install dependencies
        run: pip install requests pytest

      - name: Run CAPTCHA integration tests
        env:
          CAPTCHAAI_KEY: ${{ secrets.CAPTCHAAI_KEY }}
        run: pytest tests/test_captcha.py -v --tb=short

Stocker la clé API en tant que secret GitHub

  1. Allez dans Paramètres → Secrets et variables → Actions
  2. Cliquez sur Nouveau secret du référentiel
  3. Nom : CAPTCHAAI_KEY
  4. Valeur : votre clé API CaptchaAI
  5. Cliquez sur Ajouter un secret

Fichier de test

# tests/test_captcha.py
import os
import time
import pytest
import requests


API_KEY = os.environ.get("CAPTCHAAI_KEY")
BASE_URL = "https://ocr.captchaai.com"


def solve_recaptcha(site_key, page_url, timeout=90):
    """Solve reCAPTCHA v2 via CaptchaAI."""
    resp = requests.post(f"{BASE_URL}/in.php", data={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": site_key,
        "pageurl": page_url,
        "json": 1,
    }, timeout=30)
    result = resp.json()
    assert result.get("status") == 1, f"Submit failed: {result}"

    task_id = result["request"]
    start = time.time()

    while time.time() - start < timeout:
        time.sleep(5)
        resp = requests.get(f"{BASE_URL}/res.php", params={
            "key": API_KEY,
            "action": "get",
            "id": task_id,
            "json": 1,
        }, timeout=15)
        data = resp.json()
        if data["request"] != "CAPCHA_NOT_READY":
            assert data.get("status") == 1, f"Solve failed: {data}"
            return data["request"]

    pytest.fail("CAPTCHA solve timed out")


@pytest.mark.skipif(not API_KEY, reason="CAPTCHAAI_KEY not set")
class TestCaptchaIntegration:
    """Integration tests for CAPTCHA-protected flows."""

    def test_recaptcha_v2_solve(self):
        """Verify CaptchaAI can solve reCAPTCHA v2."""
        token = solve_recaptcha(
            site_key="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
            page_url="https://www.google.com/recaptcha/api2/demo",
        )
        assert len(token) > 100
        assert token.isascii()

    def test_balance_sufficient(self):
        """Ensure account balance is enough for test suite."""
        resp = requests.get(f"{BASE_URL}/res.php", params={
            "key": API_KEY,
            "action": "getbalance",
            "json": 1,
        })
        balance = float(resp.json()["request"])
        assert balance > 0.50, f"Low balance: ${balance}"

    def test_api_key_valid(self):
        """Verify API key is accepted."""
        resp = requests.get(f"{BASE_URL}/res.php", params={
            "key": API_KEY,
            "action": "getbalance",
            "json": 1,
        })
        result = resp.json()
        assert result.get("status") == 1, f"Invalid key: {result}"

Test matriciel (plusieurs types de CAPTCHA)

jobs:
  captcha-matrix:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        captcha-type: [recaptcha-v2, turnstile, image]
      fail-fast: false

    steps:

      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"

      - name: Install dependencies
        run: pip install requests pytest

      - name: Run ${{ matrix.captcha-type }} tests
        env:
          CAPTCHAAI_KEY: ${{ secrets.CAPTCHAAI_KEY }}
          CAPTCHA_TYPE: ${{ matrix.captcha-type }}
        run: pytest tests/test_${{ matrix.captcha-type }}.py -v

Mise en cache des résultats des tests

Évitez les résolutions CAPTCHA redondantes pour le code inchangé :


      - name: Cache test results
        uses: actions/cache@v4
        with:
          path: .test-cache
          key: captcha-tests-${{ hashFiles('tests/**') }}

      - name: Skip if cached
        id: check-cache
        run: |
          if [ -f .test-cache/passed ]; then
            echo "skip=true" >> $GITHUB_OUTPUT
          fi

      - name: Run tests
        if: steps.check-cache.outputs.skip != 'true'
        env:
          CAPTCHAAI_KEY: ${{ secrets.CAPTCHAAI_KEY }}
        run: |
          pytest tests/test_captcha.py -v
          mkdir -p .test-cache && touch .test-cache/passed

Notification Slack en cas d'échec


      - name: Notify on failure
        if: failure()
        uses: slackapi/slack-github-action@v1
        with:
          payload: |
            {
              "text": "CAPTCHA tests failed on ${{ github.ref }}",
              "blocks": [
                {
                  "type": "section",
                  "text": {
                    "type": "mrkdwn",
                    "text": "CAPTCHA tests *failed* on `${{ github.ref }}`\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View run>"
                  }
                }
              ]
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

Dépannage

Problème Parce que Corriger
Les tests sautent avec "CAPTCHAAI_KEY non défini" Secret non configuré Ajouter un secret dans les paramètres du dépôt
Timeout dans CI mais fonctionne localement Latence du réseau Runner Augmenter le délai d'attente à 120 s
La vérification du solde échoue Problème de format de clé Vérifiez que la valeur secrète n'a pas d'espace
Le workflow ne s'exécute jamais Mauvaise configuration de la branche /trigger Vérifiez le bloc on: dans YAML

FAQ

Combien coûte l’exécution de tests CAPTCHA dans CI ?

Une suite de tests typique résolvant 3 à 5 CAPTCHA coûte entre 0,01 et 0,03 $ par exécution. Les courses programmées hebdomadairement coûtent environ 0,10 à 0,15 $/month.

Dois-je exécuter des tests CAPTCHA sur chaque PR ?

Exécutez le solde et la validation des clés sur chaque PR. Exécutez des tests de résolution CAPTCHA complets lors de la fusion vers le principal ou selon un planning hebdomadaire pour minimiser les coûts.

Puis-je l'utiliser avec d'autres plateformes CI ?

Oui. Le code de test Python fonctionne de la même manière dans GitLab CI, CircleCI ou Jenkins. Seule la syntaxe YAML du workflow diffère.


Guides connexes

  • Créer un pipeline de tests automatisés
  • CAPTCHA dans les suites de tests CI

Gardez votre pipeline vert –obtenir CaptchaAIpour CI/CD.

Les commentaires sont désactivés pour cet article.