В Naumen мы используем связку Proxyman + HAR, чтобы готовить mock-данные для интеграционных тестов iOS-приложений. Такой подход выручает, когда реальный сервер недоступен или не умеет переводить себя в нужное состояние для проверки: мы перехватываем сетевой трафик приложения, сохраняем его и превращаем в готовые моки.

О том, как именно мы это делаем, рассказывает Ринат, iOS-разработчик Naumen. В его практике Proxyman помогает быстро собирать сетевые сценарии, а экспорт в HAR и консольная утилита позволяют автоматически преобразовывать их в моки для тестов. Это экономит часы ручной работы и делает интеграционные тесты стабильными и предсказуемыми.

Ринат Абидуллин

iOS-разработчик Naumen

Что такое Proxyman?

Proxyman — это инструмент для перехвата, анализа и модификации HTTP/HTTPS-трафика между устройствами и серверами. iOS-разработчики его часто используют, чтобы видеть сетевой трафик, который идет от мобильного приложения к серверу и обратно. 

Как мы используем Proxyman в тестах?

В нашей команде мы нашли для него еще одну задачу — быструю подготовку mock-данных (моков) сетевого слоя в интеграционных тестах. Это нужно в тех случаях, когда реальный сервер недоступен или не умеет переводить себя в нужное для теста состояние.

Интеграционный тест — это вид тестирования программного обеспечения, при котором отдельные модули или компоненты системы объединяются и тестируются совместно. Такие тесты позволяют убедиться, что различные части приложения, например, пользовательский интерфейс, бизнес-логика, базы данных, сетевые взаимодействия, правильно работают вместе.

Чтобы тесты не зависели от внешних систем, мы подменяем ответы сервера на моки. Это позволяет:

  • проверять взаимодействие внутренних компонентов приложения без «живого» сервера;

  • имитировать ответы сервера и контролировать тестовые сценарии;

  • обеспечивать стабильность и предсказуемость тестов.

Так мы можем сфокусироваться на проверке внутренней логики приложения и его способности правильно обрабатывать различные ответы, не беспокоясь о доступности или поведении реального сервера.

Как это выглядит на практике?

У нас есть продукты, в которых мы применяем подход с подменой ответов от сервера на моки, например ChatSDK. Делается это достаточно просто:

  • Запускаем Proxyman.

  • Запускаем мобильное приложение.

  • Проходим «голден-кейс», для которого хотим написать тест, в мобильном приложении — воспроизводим действия пользователя: нажимаем на кнопки, вводим данные, свайпаем и т.д.

  • В Proxyman экспортируем перехваченный трафик как HAR-файл (HTTP Archive).

  • Преобразуем HAR-файл в моки для теста.

Как мы автоматизировали преобразование HAR?

Чтобы не тратить часы на ручное копирование JSON-ответов, мы написали консольную утилиту для преобразования HAR-файла в моки. 

Пример части кода моков, который генерирует утилита:

struct SendingAttachmentsInChatHttpScenario: Scenario {
    let scenarioId: ScenarioIdentifier = .sendingImageAttachmentsInChat

    let responseQueue: [ResponseQueueItem] = [
        ResponseQueueItem(
            requestResponse: RequestResponseItem(
                condition: { request in
                    request.url == URL(
                        string: "https://example.com/authorize/"
                    )!
                },
                response: HTTPURLResponse(
                    url: URL(string: "https://example.com/authorize/")!,
                    statusCode: 200,
                    httpVersion: "HTTP/1.1",
                    headerFields: [
                        "Content-Type": "application/json"
                    ]
                )!,
                data: #"""
                {
                  "authData" : {
                    "customerId" : "6216",
                    "visitorId" : "9291"
                  }
                }
                """#
                .data(using: .utf8)
            ),
            repeatability: .once,
            callStatus: .notCalled
        ),
        ...
    ]
}

На что стоит обратить внимание в реализации?

Если захотите применить этот подход в своем проекте, вот несколько технических деталей:

  • Управлять тем, какие конкретно моки выбрать при запуске теста, нужно через аргументы запуска мобильного приложения CommandLine.arguments.

  • При запуске тестов нужно отдавать моковые данные на запросы, реализуется это в классе-наследнике от URLProtocol, который нужно передать в конфигурацию сетевой сессии.

  • Для перехвата WebSocket-событий в Proxyman нужно настроить socksV5Proxy не только в коде мобильного приложения, передав его в конфигурацию сетевой сессии. Но и в самом Proxyman.

Для этого переходим в Tools → Proxy Settings → SOCKS Proxy Settings, ставим галочку Enable SOCKS Proxy и задаем порт, например, 8889.

Имитировать WebSocket-события можно через DarwinNotificationCenter, так как нужно настраивать взаимодействие между несколькими процессами — тестируемым мобильным приложением и тест-раннером.

Какой результат дает подход?

Proxyman + HAR + CLI-утилита — это простой и надежный способ превращать реальный сетевой трафик в готовые mock-данные для iOS-тестов. Подход экономит время, позволяет сосредоточиться на логике приложения и делает интеграционные тесты стабильными.

Комментарии (0)