Тестирование интеграции CAPTCHA на Go без расходования средств

Автор: solvethree3 мин на чтение

Направьте официальный Go SDK на сервер httptest с помощью NewClientWithBaseURL. Сервер предоставляет ответы для задачи, поэтому вы можете проверить SDK, не расходуя средства на балансе solvethree и не передавая секреты приложения.

На этой странице

Запуск SDK с локальной тестовой заглушкой

  1. 1.

    Установите зависимость

    Используйте Go 1.22 или новее. В своём модуле Go установите solvethree.com/[email protected] с помощью go get. Модуль доступен на solvethree.com.

  2. 2.

    Сохранение и запуск теста

    Сохраните пример как captcha_integration_test.go в каталоге вашего модуля, предназначенном только для тестов, затем выполните go test из этого каталога. Не меняйте ключ, имя хоста и прокси в заглушке: это тестовые данные, а не учётные данные или сервисы, которые нужно настраивать.

Go · изолированный интеграционный тест 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 допускает HTTP через loopback для тестов. Здесь server.URL заменяет адрес рабочего API, а обработчик отвечает локально. Значение прокси — лишь часть отправленной задачи; заглушка к нему не подключается.

Что подтверждает успешное прохождение теста

Ответ на POST оставляет задачу в ожидании. Следующий запрос получает ответ о готовности, содержащий FIXTURE_TOKEN. Финальная проверка проверяет и возвращённый токен, и наличие ровно одного POST, выявляя случайное создание дополнительной задачи в этом процессе.

Обработчик намеренно упрощён: любой запрос, кроме POST, получает ответ о готовности. Он не проверяет метод опроса, путь запроса или отправленный JSON. Чтобы также проверить контракт запросов, добавьте в обработчик проверку ожидаемых маршрутов создания и получения задачи, а также переданных сайта, действия и прокси.

Успешное прохождение теста подтверждает работу смоделированного жизненного цикла SDK. Оно не проверяет реальный профиль сайта, прокси или принятие токена целевым сервисом. Возвращённый токен и идентификационные данные браузера — тестовые значения.

Добавьте сценарии ошибок в точках принятия решений вашей интеграцией

Расширьте локальный обработчик, чтобы он возвращал состояния, которые должно обрабатывать ваше приложение. Сохраните счётчик POST: повторный опрос не должен создавать ещё одну задачу.

Дополнительные тестовые сценарии — пример выше их не покрывает
Дополнительные тестовые сценарии — пример выше их не покрывает
Поведение тестовой заглушкиЧто проверить
Запрос опроса возвращает HTTP 429, 502, 503 или 504, а затем ответ о готовности.Solve повторяет опрос при временных сбоях, учитывает Retry-After в пределах установленного срока и по-прежнему отправляет только один POST.
Задача завершается с ошибкой: errorCode имеет значение site-unreachable, также возвращается сообщение об ошибке.Обработайте *solvethree.TaskFailedError и прекратите опрос этой задачи. Её ErrorCode определяет причину сбоя; получите неуспешную задачу, если нужен текст её Error.
Создание возвращает неуспешный HTTP-ответ.Обработайте HTTP-ошибку, а не считайте ответ успешным созданием задачи. Используйте errors.As, чтобы извлечь *solvethree.APIError и проверить StatusCode.
Задача остаётся в ожидании до истечения установленного срока.Определяйте context.DeadlineExceeded с помощью errors.Is. Тайм-аут прекращает ожидание, но не отменяет работу на сервере.
Сервер регистрирует создание, но клиент теряет ответ.Проверьте данные для восстановления в *solvethree.Error. CreateTask не повторяет POST автоматически. Восстановите работу с помощью GetTask, если известен TaskID, или повторно отправьте исходные входные данные без изменений с тем же RequestID.

Для сценария потери ответа явно задайте в тесте идентификатор запроса и настройте заглушку так, чтобы при повторной отправке этого идентификатора и тех же входных данных она возвращала существующую задачу. Иначе вы проверяете второе создание, а не восстановление.

Запустите первую задачу.

Начните с $5 на балансе рабочего пространства.

Создать рабочее пространство
Тестирование интеграции CAPTCHA на Go без расходования средств · solvethree