Teste uma integração de CAPTCHA em Go sem gastar créditos
Aponte o SDK oficial de Go para um servidor httptest usando NewClientWithBaseURL. O servidor fornece as respostas das tarefas, permitindo testar o SDK sem gastar créditos da solvethree nem fornecer segredos da aplicação.
Nesta página
Execute o SDK com uma fixture local
- 1.
Instale a dependência
Use Go 1.22 ou posterior. No seu módulo Go, use
go getpara instalarsolvethree.com/[email protected]. O módulo é disponibilizado em solvethree.com. - 2.
Salve e execute o teste
Salve o exemplo como
captcha_integration_test.goem um diretório exclusivo para testes dentro do seu módulo e executego testnesse diretório. Mantenha a chave, o hostname e o proxy da fixture inalterados: são dados de teste, não credenciais ou serviços que você precisa configurar.
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 aceita HTTP de loopback para testes. Aqui, server.URL substitui o endereço da API de produção, e o handler responde localmente. O valor do proxy é apenas parte da tarefa enviada; esta fixture não se conecta a ele.
O que a aprovação no teste comprova
A resposta ao POST deixa a tarefa pendente. Uma requisição posterior recebe uma resposta de tarefa pronta contendo FIXTURE_TOKEN. A asserção final verifica tanto o token retornado quanto a ocorrência de exatamente um POST, detectando uma criação extra acidental de tarefa durante esse fluxo.
O handler é propositalmente simples: toda requisição que não seja POST recebe a resposta de tarefa pronta. Ele não verifica o método de polling, o caminho da requisição nem o JSON enviado. Para testar também o contrato da requisição, faça o handler verificar as rotas esperadas de criação e consulta de tarefas, além do site, da ação e do proxy enviados.
A aprovação neste teste comprova que o ciclo de vida simulado do SDK funciona. Ela não valida um perfil de site real, um proxy nem a aceitação do token pelo destino. O token e a identidade do navegador retornados são valores da fixture.
Adicione casos de falha nos pontos de decisão da sua integração
Amplie o handler local para retornar as condições que sua aplicação precisa tratar. Mantenha o contador de POSTs: repetir uma consulta de polling não deve criar outra tarefa.
| Comportamento da fixture | O que verificar |
|---|---|
| Uma requisição de polling retorna HTTP 429, 502, 503 ou 504 e, depois, o estado pronto. | Solve repete as consultas de polling após falhas temporárias, respeita Retry-After dentro do prazo e ainda envia apenas um POST. |
| A tarefa passa ao estado de falha com errorCode site-unreachable e uma mensagem de erro. | Trate *solvethree.TaskFailedError e pare de consultar essa tarefa. Seu ErrorCode identifica a falha; consulte a tarefa que falhou quando precisar do texto de Error. |
| A criação retorna uma resposta HTTP sem sucesso. | Trate o erro HTTP em vez de considerar a resposta uma tarefa bem-sucedida. Use errors.As para extrair *solvethree.APIError e inspecionar StatusCode. |
| A tarefa permanece pendente até o prazo limite. | Identifique context.DeadlineExceeded com errors.Is. Um timeout interrompe a espera; ele não cancela o trabalho remoto. |
| O servidor registra a criação, mas o cliente perde a resposta. | Verifique as informações de recuperação em *solvethree.Error. CreateTask não repete o POST automaticamente. Recupere com GetTask quando TaskID for conhecido ou reenvie exatamente os parâmetros originais com o mesmo RequestID. |
Para o caso de resposta perdida, forneça ao teste um ID de requisição explícito e faça a fixture retornar a tarefa existente quando esse ID e os mesmos parâmetros forem reenviados. Caso contrário, você estará testando uma segunda criação, não uma recuperação.
Fontes e referência da API
Execute sua primeira tarefa.
Comece com $5 em créditos no espaço de trabalho.