Тестирование интеграции CAPTCHA на Go без расходования средств
Направьте официальный Go SDK на сервер httptest с помощью NewClientWithBaseURL. Сервер предоставляет ответы для задачи, поэтому вы можете проверить SDK, не расходуя средства на балансе solvethree и не передавая секреты приложения.
На этой странице
Запуск SDK с локальной тестовой заглушкой
- 1.
Установите зависимость
Используйте Go 1.22 или новее. В своём модуле Go установите
solvethree.com/[email protected]с помощьюgo get. Модуль доступен на solvethree.com. - 2.
Сохранение и запуск теста
Сохраните пример как
captcha_integration_test.goв каталоге вашего модуля, предназначенном только для тестов, затем выполнитеgo testиз этого каталога. Не меняйте ключ, имя хоста и прокси в заглушке: это тестовые данные, а не учётные данные или сервисы, которые нужно настраивать.
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. |
Для сценария потери ответа явно задайте в тесте идентификатор запроса и настройте заглушку так, чтобы при повторной отправке этого идентификатора и тех же входных данных она возвращала существующую задачу. Иначе вы проверяете второе создание, а не восстановление.
Источники и справочник API
Запустите первую задачу.
Начните с $5 на балансе рабочего пространства.