Tester une intégration CAPTCHA en Go sans dépenser de crédit

Par solvethree4 min de lecture

Faites pointer le SDK Go officiel vers un serveur httptest à l’aide de NewClientWithBaseURL. Le serveur fournit les réponses des tâches : vous pouvez ainsi tester le SDK sans dépenser de crédit solvethree ni fournir de secrets de l’application.

Sur cette page

Exécuter le SDK avec un dispositif de test local

  1. 1.

    Installez la dépendance

    Utilisez Go 1.22 ou une version ultérieure. Dans votre module Go, utilisez go get pour installer solvethree.com/[email protected]. Le module est distribué depuis solvethree.com.

  2. 2.

    Enregistrer et exécuter le test

    Enregistrez l’exemple sous le nom captcha_integration_test.go dans un répertoire réservé aux tests au sein de votre module, puis exécutez go test depuis ce répertoire. Ne modifiez pas la clé, le nom d’hôte ni le proxy du dispositif de test : ce sont des données de test, pas des identifiants ni des services à configurer.

Go · un test d’intégration isolé du SDK
package integration_test

import (
    "context"
    "fmt"
    "net/http"
    "net/http/httptest"
    "sync/atomic"
    "testing"
    "time"
    solvethree "solvethree.com/sdk"
)

func TestSolve(t *testing.T) {
    var posts atomic.Int32
    server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        if r.Method == "POST" {
            posts.Add(1)
            fmt.Fprint(w, `{"id":"fixture-1","status":"pending"}`)
            return
        }
        fmt.Fprint(w, `{"id":"fixture-1","status":"ready","solution":{"token":"FIXTURE_TOKEN","userAgent":"fixture-browser-identity","secChUa":"fixture-hints"}}`)
    }))
    defer server.Close()
    client, err := solvethree.NewClientWithBaseURL("fixture-key", server.URL, nil)
    if err != nil { t.Fatal(err) }
    result, err := client.Solve(context.Background(), solvethree.TaskRequest{
        Site: "accounts.example.com", Action: "login", Proxy: "http://proxy.example:8080",
    }, solvethree.SolveOptions{Timeout: time.Second, PollInterval: time.Millisecond})
    if err != nil { t.Fatal(err) }
    if result.Solution.Token != "FIXTURE_TOKEN" || posts.Load() != 1 { t.Fatal("incorrect lifecycle") }
}

NewClientWithBaseURL accepte HTTP sur l’interface de bouclage pour les tests. Ici, server.URL remplace l’adresse de l’API de production et le gestionnaire répond localement. La valeur du proxy fait simplement partie de la tâche envoyée ; ce dispositif de test ne s’y connecte pas.

Ce que prouve la réussite du test

La réponse POST laisse la tâche en attente. Une requête ultérieure reçoit une réponse indiquant que la tâche est prête et contenant FIXTURE_TOKEN. L’assertion finale vérifie à la fois le jeton renvoyé et la présence d’exactement un POST, ce qui détecte la création accidentelle d’une tâche supplémentaire pendant ce déroulement.

Le gestionnaire reste volontairement minimal : toute requête autre que POST reçoit la réponse indiquant que la tâche est prête. Il ne vérifie ni la méthode d’interrogation, ni le chemin de la requête, ni le JSON envoyé. Pour tester aussi le contrat de requête, faites vérifier au gestionnaire les routes attendues de création et de récupération des tâches, ainsi que le site, l’action et le proxy envoyés.

La réussite de ce test prouve que le cycle de vie simulé du SDK fonctionne. Elle ne valide ni un profil de site réel, ni un proxy, ni l’acceptation du jeton par la cible. Le jeton renvoyé et l’identité du navigateur sont des valeurs de test.

Ajouter des cas d’échec aux points de décision de votre intégration

Étendez le gestionnaire local pour qu’il renvoie les situations que votre application doit gérer. Conservez le compteur de POST : réessayer une interrogation ne doit pas créer une autre tâche.

Cas de test supplémentaires — non couverts par l’exemple ci-dessus
Cas de test supplémentaires — non couverts par l’exemple ci-dessus
Comportement du dispositif de testPoints à vérifier
Une requête d’interrogation renvoie HTTP 429, 502, 503 ou 504, puis un état prêt.Solve réessaie après les échecs temporaires d’interrogation, respecte Retry-After dans la limite du délai imparti et n’envoie toujours qu’un seul POST.
La tâche passe à l’état d’échec avec errorCode égal à site-unreachable et un message d’erreur.Gérez *solvethree.TaskFailedError et cessez d’interroger cette tâche. Son champ ErrorCode identifie l’échec ; récupérez la tâche échouée si vous avez besoin du texte de son champ Error.
La création renvoie une réponse HTTP qui n’indique pas un succès.Gérez l’erreur HTTP au lieu de traiter la réponse comme une tâche créée avec succès. Utilisez errors.As pour extraire *solvethree.APIError et examiner StatusCode.
La tâche reste en attente jusqu’à l’expiration du délai.Détectez context.DeadlineExceeded avec errors.Is. L’expiration du délai met fin à l’attente ; elle n’annule pas le travail distant.
Le serveur enregistre la création, mais le client perd la réponse.Vérifiez les informations de reprise sur *solvethree.Error. CreateTask ne réessaie pas automatiquement le POST. Reprenez avec GetTask si TaskID est connu, ou renvoyez exactement les données d’entrée d’origine avec le même RequestID.

Pour le cas de perte de réponse, donnez au test un identifiant de requête explicite et faites renvoyer la tâche existante par le dispositif de test lorsque cet identifiant et les mêmes données d’entrée sont renvoyés. Sinon, vous testez une seconde création, pas une reprise.

Lancez votre première tâche.

Démarrez avec $5 de crédit dans votre espace de travail.

Créer un espace de travail
Tester une intégration CAPTCHA en Go sans dépenser de crédit · solvethree