Почему данные с сервера не приходят в приложение на реальное устройство?
При запуске приложения отправляется запрос на сервер (который находится на компьютере локально) на получение списка постов (аналог стены в Vk). По идее, сервер должен обработать запрос и вернуть этот список постов. Но он ничего не возвращает. В LogCat никаких ошибок не выдаёт, но при дебаге, вместо ответа от сервера, приходит исключение:
((SocketTimeoutException)e).detailMessage = failed to connect to /192.168.1.35 (port 9999) from /192.168.1.33 (port 49742) after 30000ms
При попытке добавить новый пост (отправить пост на сервер методом Post), выдаёт ошибку в LogCat. Вот текст ошибки:
2021-11-02 21:17:29.025 12197-12210/ru.example E/SpellCheckerSession: ignoring processOrEnqueueTask due to unexpected mState=TASK_CLOSE scp.mWhat=TASK_CLOSE 2021-11-02 21:17:39.811 12197-12568/ru.example E/AndroidRuntime: FATAL EXCEPTION: Thread-4 Process: ru.example, PID: 12197 java.net.SocketTimeoutException: failed to connect to /192.168.1.35 (port 9999) from /192.168.1.33 (port 49918) after 30000ms at libcore.io.IoBridge.connectErrno(IoBridge.java:185) at libcore.io.IoBridge.connect(IoBridge.java:130) at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:129) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:356) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:357) at java.net.Socket.connect(Socket.java:616) at okhttp3.internal.platform.AndroidPlatform.connectSocket(AndroidPlatform.kt:63) at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.kt:295) at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:207) at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226) at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106) at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74) at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255) at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201) at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154) at ru.example.repository.PostRepositoryImpl.save(PostRepositoryImpl.kt:60) at ru.example.viewmodel.PostViewModel$save$1$1.invoke(PostViewModel.kt:54) at ru.example.viewmodel.PostViewModel$save$1$1.invoke(PostViewModel.kt:53) at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)
IP-адрес и порт указаны верно. На родном эмуляторе от android-studio указываю адрес 10.0.2.2:9999 — посты приходят. На эмуляторе Genymotion, у которого свой IP, указываю адрес 192.168.1.35:9999 — тоже приходит ответ от сервера. Не приходит ответ только на реальные устройства (Xiaomi Redmi 5 и Nexus 5X). Помогите разобраться с проблемой, пожалуйста!
Как съэмитировать ошибку сервера в android studio
Снифферы — это инструменты, позволяющие перехватывать, анализировать и модернизировать все запросы, которые через них проходят. Они полезны, когда из потока нужно извлечь какие-либо сведения или создать нужный ответ сервера. Так можно проводить модульное тестирование продукта, в котором есть и бэк, и фронт, и разные команды со своей версионностью.
В этой статье я расскажу об основных функциях снифферов, которые могут быть полезны QA. Попробую не вдаваться в теорию, а сфокусироваться на практике. Наиболее популярными представителями анализаторов трафика сейчас являются WhireShark, Fiddler и Charles Proxy. Об удобстве интерфейсов и функционале каждого из них можно рассуждать долго, учитывая все плюсы и минусы. Но здесь я отдал предпочтение Charles, поскольку сам им активно пользуюсь. Буду рассказывать на его примере.
Что собой представляет Charles Proxy
Charles Web Debugging Proxy — это инструмент мониторинга HTTP и HTTPS трафика. Он выступает в роли прокси-сервера (промежуточного звена) между тестируемым приложением и сервером на бэкенде, позволяя не только видеть, но также перехватывать и редактировать запросы.
Главное преимущество Charles Proxy и снифферов в целом — возможность просмотра трафика, в том числе с мобильных устройств, что значительно облегчает работу тестировщика клиент-серверных мобильных приложений.
Первичная настройка
При тестировании мобильного приложения
Charles Proxy необходимо запустить на компьютере, который находится в той же локальной подсети, что и мобильное устройство с тестируемым приложением.
Как правило, соединение настраивается по Wi-Fi. В настройках Wi-Fi мобильного устройства в качестве proxy-сервера надо указать IP-адрес компьютера и стандартный порт инструмента 8888 (пароль остается пустым).
IP-адрес компьютера можно узнать через командную строку (ipconfig) или в самом Charles Proxy (Help -> Local IP Address).

Этот же адрес есть в инструкции по подключению, доступной в Help -> SSL Proxying -> Install Charles Root Certificate on mobile device remote browser.
После сохранения настроек Charles Proxy сможет читать HTTP-трафик мобильного устройства. Но чтобы смотреть расшифрованный трафик HTTPS, нужны дополнительные манипуляции — требуется установить SSL-сертификат Charles Proxy в браузере на мобильном устройстве.
Скачать сертификат можно по адресу: chls.pro/ssl (адрес, по которому скачивается сертификат, также можно найти в инструкции Help -> SSL Proxying -> Install Charles Root Certificate on mobile device remote browser). Далее в iOS его необходимо сделать доверенным (в Настройки -> Основные -> Профили).

В Android установленные сертификаты верифицируются в Settings -> Trusted Credentials на вкладке User.
Главное отличие в настройках для этой ОС в том, что с Android 6.0 и выше в Androidmanifest надо добавить специальную конфигурацию, позволяющую просматривать защищенный трафик. На продакшене эта конфигурация убирается из соображений безопасности.
При тестировании приложения на ПК
В этом случае дополнительные сертификаты нужно установить на сам ПК. Для скачивания и установки нужна ссылка из Help -> SSL Proxying -> Install Charles Root Certificate.

Сертификат устанавливается в доверенные корневые центры.
Два слова об интерфейсе

Интерфейс Charles Proxy прост. Слева — список перехваченных запросов, справа — детали.
В списке запросов есть две основные вкладки — Structure и Sequence.
В первом случае запросы рассортированы по хостам-папкам. Наведя на любой из них, можно получить всю информацию о количестве запросов к этому корневому хосту, доле удачных, таймингах, размерах и т.п. Фактически, здесь представлена вся та же информация, которую можно получить из панели разработчика в браузере. Выбрав конкретный URL, можно увидеть код ответа, версии протоколов, контент и т.п. Тело запроса, заголовки, cookie (если есть) можно посмотреть в разных форматах — даже в HEX.
С помощью контекстного меню запроса можно настраивать блокировки, повторять и изменять запросы. На этом мы еще остановимся.
На вкладке Sequence запросы выведены по времени в виде настраиваемой таблицы. Видно, когда начался запрос, сколько он длился, его размер, статус и т.п. Наведя на конкретную строку, мы получим ту же информацию о теле, заголовках и т.п.
Если запросов на экране слишком много, с помощью панели инструментов их можно очистить или вообще остановить перехват. Там же есть возможность включить и выключить троттлинг (подробнее об этих функциях расскажу позже). Базовая настройка каждой из функций осуществляется через меню, а кнопки панели управления выступают своего рода тумблерами On / Off.
Фильтрация
В Charles Proxy очень много вариантов фильтрации запросов.
Начнем с вкладки Structure. Самое примитивное — скопировать хост и вставить в поле Filter. Так мы увидим только запросы с этого хоста. Примерно того же результата можно добиться, если в контекстном меню хоста выбрать Focus. Остальные запросы будут собраны в Other Hosts. Если при этом перейти на закладку Sequence и отметить настройку Focused, то в списке окажется информация только о тех запросах, которые были выбраны на вкладке Structure.
На вкладке Sequence есть аналогичный фильтр.
Charles Proxy умеет работать с регулярными выражениями. Для этого на вкладке Sequence выбираем Settings и отмечаем пункт Filter uses regex. И вписываем в поле поиска элементарную регулярку.
Например, вот так
можно выбрать все запросы, в которых в начале имени хоста находится четыре буквы, а потом идет точка.
Там же можно включить Autoscroll списка запросов или указать максимальное количество строк.
В Charles Proxy можно фильтровать не только отображение, но и запись запросов. Для этого надо зайти в Proxy -> Record settings и задать условия на одной из вкладок — Include или Exclude — так мы включаем или выключаем запись запросов данного хоста.
Похожего результата можно добиться, используя блок-листы. Включить хост в блок лист можно из контекстного меню (команда Block list) или через добавление в Tools -> Block list, где следует отметить Enable Block list.
Блокируемый запрос можно прервать двумя способами (подходящий надо выбрать в настройках):
- сбросить соединение;
- вернуть ошибку 403.
От выбранного способа блокировки зависит, какой ответ мы получим.
Можно провести эксперимент. Включим наш тестовый стенд в Block list, выбрав простой сброс соединения. С помощью контекстного меню запроса повторим его (команда Repeat) и получим такой ответ:

Статус запроса — Failed, а в описании ошибки указано, что Connection dropped.
Просмотр SSL-трафика
Если ранее мы успешно установили SSL-сертификат, для просмотра зашифрованного трафика остается только включить SSL proxying для нужного хоста в самом Charles Proxy. Это можно сделать через контекстное меню конкретного хоста.

Чтобы не включать каждый хост, можно зайти в Proxy -> SSL Proxying settings и на первой вкладке SSL Proxying включить Enable SSL Proxying.
Аналогично настройке фильтров на вкладках Include и Exclude можно добавить или исключить конкретные хосты. Если списки на этих вкладках не заполнять, по умолчанию мы будем читать трафик со всех хостов.
Брейкпоинты
Наверное, одна из самых популярных функций Charles Proxy — это настройка точек остановки, которые позволяют перехватывать запросы.
Установить Breakpoint можно из контекстного меню запроса. После этого все аналогичные запросы будут перехвачены. Их можно будет просматривать и редактировать.

Чтобы проверить, как это работает можно использовать повтор запроса (Repeat из того же контекстного меню). Запрос перехватывается, его можно редактировать.
В принципе, изменить можно все — от header до авторизационного токена. Когда редактирование будет закончено, можно выбрать Execute и в Charles Proxy появится повторный запрос, который и отправится на сервер, а потом вернется с ответом. В этот момент можно будет посмотреть и отредактировать ответ, который получит приложение — появится поле Edit response.
Оставайтесь на связи.
Мы в соцсетях:
Редактируя запрос, можно ввести заведомо некорректные данные и посмотреть, как ответит сервер. Также можно отредактировать ответ (внеся некорректные данные) и использовать его для тестирования фронта. Можно оставить корректные данные, но изменить код — посмотреть, как фронт воспринимает информацию, переданную через API.
Map remote
Еще одна популярная функция Charles Proxy — подмена ответа сервера. Так мы можем ответ одного хоста подменить на ответ другого. Настраивается это через Tools -> Map Remote.

Обратите внимание, в левом нижнем углу есть кнопки Import и Export. Они позволяют обмениваться настройками — переносить их с одного рабочего места на другое.
Например, мы можем подменить контура. Я буду посылать запрос на dev-контур, но ответ хочу получить с тестового стенда. Для этого создаем новый пункт в списке Map Remote Settings. Map From — куда изначально был запрос; Map to — откуда берем ответ.
Эта функция может быть полезна, если мы поймали ошибку на продакшене, например при загрузке таблицы, а информации в dev-контуре для полноценного тестирования не хватает. Вместо того, чтобы перезаполнять информацию в каждом контуре, мы можем скопировать ответ сервера в нужный контур и посмотреть, как он ведет себя после исправления ошибки.
Map Local
Главное отличие Map Local от предыдущей функции в том, что замена осуществляется не на ответ другого сервера, а на содержимое локального файла. Настройки выглядят точно также, но вместо второго сервера мы указываем локальный путь к файлу с ответом.
Rewrite
Функция Rewrite может быть полезна, если вам нужно переписать данные, которые отправляются в Charles Proxy. В отличие от простого редактирования Rewrite позволяет задать правила изменения и работать в автоматическом режиме. Можно изменять и добавлять заголовки, искать и заменять текст в теле запроса или ответа. Можно даже менять статус ответа.
Rewrite удобно использовать, когда нужен готовый ответ, но мы не хотим каждый раз ставить брейкпоинт и вписывать его в ручную. Редактируя таким образом ответ, фактически, мы ставим заглушку — можем имитировать работу сторонних партнеров. Честно говоря, в Postman-е эта функция реализована более интуитивно. Но раз мы говорим про Charles, не будем отходить от его примера.
Настроить это можно через Rewrite settings, доступные в контекстном меню. Единственный недостаток инструмента в том, что каждое правило замены прописывается отдельно.
Помимо изменения запросов и ответов мы можем запретить кэширование или cookie (функции No caching и Block cookies). Эти опции повторяют аналогичные инструменты панели разработчика в браузере. В обоих случаях настраивается список хостов, для которых действует настройка. Если же список пуст, то кэширование и cookie отключаются на всех перехваченных хостах.
Throttling
Charles Proxy помогает тестировать сервис на плохой связи, искусственно ограничив через настройки пропускную способность канала. Эта функция полезнее всего для тестирования десктопных приложений, поскольку на мобильных устройствах качеством связи можно управлять через панель разработчика.
Настраивается функция через Proxy ->Throttling settings.

Ограничения можно включить либо для хостов из списка, либо для всех перехваченных запросов. Из коробки есть несколько пресетов, но все параметры связи можно корректировать вручную. Мне по большей части хватает базовых настроек.
Repeat Advanced
Хотя полноценное нагрузочное тестирование лучше проводить в специальных инструментах, Charles Proxy имеет одну базовую настройку, которая помогает закрыть минимальные потребности. Функция Repeat Advanced (доступная через контекстное меню перехваченного запроса) позволяет нужное количество раз повторить тот же запрос. После настройки откроется отдельная сессия, где будут видны детали каждого из запросов.
Конечно, список функций Charles Proxy этим не ограничивается. Есть еще много полезного — от перенаправления доменного имени на другой IP-адрес, до автоматического сохранения полученных ответов.
Отмечу, что Charles Proxy платный. Можно использовать триальную версию. Но раз в 5-7 минут поверх него будет отображаться всплывающее окно с версией, а раз в 30 минут он будет выключаться, при этом сессии не сохраняются. Решайте сами, помешает ли это вашей работе.
В целом Charles Proxy — это хороший инструмент. Не сказал бы, что он сильно отличается от того же Fiddler-а, но на мой взгляд он больше заточен под MacOS, поскольку пришел на эту платформу раньше. Хотя сейчас уже нельзя сказать, что какой-то сниффер принципиально лучше или хуже. Все они решают примерно одни и те же задачи сходным образом.
Автор статьи: Артем Холевко, Максилект.
Текст подготовлен по материалам внутреннего семинара Максилект.
Наши статьи по теме:
- Как мы мигрировали сервера в новый дата-центр и, кажется, не сошли с ума
- “Кем вы себя видите в нашей компании через 5 лет” и другие надоевшие вопросы HR — откуда они взялись и как мешают найму
- Clickhouse — непростая жизнь в продакшене
- О контроле на удаленке: как совместить спокойствие бизнеса и доверие разработчикам
- Фокус-менеджмент вместо тайм-менеджмента
Погружение в Charles Proxy
Привет, Хабр! Статья была ранее опубликована в блоге компании, который сейчас удален. Перевыкладываю, так как считаю, что статья не потеряла актуальность на текущий момент времени.
При приёмке задач мы уделяем большое внимание проверке клиент-серверного взаимодействия. Опыт проведения собеседований показывает, что новички в тестировании мобильных приложений ограничиваются интерфейсными проверками, упуская из виду то, что за каждым изменением интерфейса стоит отправка запроса к серверу и получение ответа от него. Здесь и возникает пространство для ошибок.
Если повезло, то кандидат знает о необходимости проверки сетевого взаимодействия, но, за редким исключением, его знания ограничены Rewrite или Breakpoints.
Сегодня я расскажу, с какими задачами сталкиваются тестировщики мобильных приложений и как в этом помогает Charles Proxy.
Случай из жизни
Прежде чем двигаться дальше, сравните два кейса, которые подчеркнут важность проверок на сетевом уровне.
Ситуация 1: тестировщик пропускает баг вёрстки счётчика подписчиков для пользователя, у которого больше миллиона фолловеров. Неприятно, но на ценности продукта для пользователя сильно не скажется.
Ситуация 2: в приложение добавлена настройка получения push-уведомлений. Проверяя их отключение, тестировщик увидел подтверждение и посчитал сценарий пройденным. После релиза посыпались жалобы пользователей на слишком большое количество уведомлений, им приходилось отключать их на уровне ОС или удалять приложение. Для бизнеса такая ситуация критична: метрики искажаются, а пользователи утекают.
Почему так произошло? На бэкенде раскатили неудачный коммит, и на запрос отключения уведомлений возвращалась ошибка сервера. Мобильный клиент не обрабатывал получение кода 500, но тестировщик и пользователь видели попап отписки, хотя она не происходила. Если бы тестировщик обратил внимание на нестандартный код ответа API, то проблему быстро бы обнаружили и решили. Правда, в этот случай ещё вмешался сломанный мониторинг и отсутствие тестов на бэкенд, но всегда помните, что вы можете оказаться единственным тестировщиком на задаче или продукте и перепроверить будет некому.
К чему это всё? К тому, что использование сниффера может избавить вас от таких ошибок.
Что мы используем?
Charles Proxy в моей компании стал стандартом де-факто. Этот инструмент предоставляет множество возможностей и в то же время прост в использовании, что снижает порог входа. Так тестировщики, разработчики и менеджеры находятся в одном информационном поле.
При тестировании задач мы придерживаемся нескольких правил. Во-первых, проксируем трафик приложения, включаем расшифровку тех SSL-соединений, которые необходимы. Во-вторых, обращаем внимание на то, какие ручки используются, какое количество запросов отправляется, какие коды ответов возвращаются.
Задача 1. Слушаем, смотрим, анализируем
Подготовка
Если знаете, как установить Charles в связке с мобильным устройством, можете смело пропускать эту часть.
- Устанавливаем и запускаем Charles Proxy.
- Для расшифровки SSL-соединений потребуется установка сертификата. Переходим по ссылке chls.pro/ssl на тестовом устройстве.
- Для iOS необходимо дополнительно подтвердить доверие сертификату в настройках: General -> About -> Trust Certificates. Для Android 7.0 и выше в код приложения должен быть добавлен network_security_config. Подробно описывается здесь.
- Настраиваем проксирование через Charles:
- если ПК c Charles и тестовое устройство принадлежат одной Wi-Fi сети, переходим в настройки Wi-Fi тестового девайса, прописываем настройки прокси-сервера: IP-адрес устройства, на котором запущен Charles, в поле Server (Hostname), порт 8888;
- если ПК с Charles подключен к проводной сети, но с него можно раздать Wi-Fi, то делаем это;
- если ПК с Charles подключен к проводной сети и раздать интернет с него нельзя, нам понадобится дополнительное устройство, способное раздавать беспроводной интернет (роутер), на нём настраиваем Port Forwarding на адрес нашего ПК. Ищем «проброс портов ».
- После того как мы связали тестовое устройство и ПК со сниффером, в Charles появится запрос на разрешение подключиться мобильному устройству.
- Включаем SSL Proxying Settings на нужных хостах.
Результат шага: мы запустили Charles, отображается трафик приложения, а также соединения рекламных и системных сервисов.
Примечание 1: по дефолту трафик ПК будет также проходить через Charles. Чтобы в сниффере отображался только трафик подключенных устройств, снимаем галку в настройках проксирования.
Примечание 2: мы не включаем расшифровку сетевых соединений на все хосты сразу, т.к. это помешает проверке сценариев интеграции со сторонними сервисами (Twitter, Facebook, и т.д), покупки и прочего — самоподписанный сертификат Charles не вызовет доверия.
Фильтрация информации
Найти интересующую тестировщика информацию можно несколькими способами.
Structure view + Focus Mode
Представление Structure view удобно, если хотим узнать, к каким ручкам выполняется обращение. Список проксируемых ручек отображается слева. Выберем конкретный запрос и в правой части увидим информацию о нём. Во вкладке Overview будет техническая информация по статусу соединения, коду ответа, времени отправки запроса и времени получения ответа и так далее, во вкладке Contents можно выбрать формат и заглянуть в тело запроса или ответа, а также посмотреть заголовки.
Для уменьшения количества хостов в левой части на помощь придёт Focused Mode. Находим нужную ручку, вызываем контекстное меню, выбираем Focus.
Теперь ручки, для которых выбран Focus, будут закреплены в верхней части списка. Остальные сгруппированы в Other Hosts.
Примечание: в Charles можно уровнем выше настроить хосты, информация об обращении к которым будет записана в сессию, но часто удобно знать обо всём трафике, который проходит через приложение.
Да, стало проще искать информацию о конкретных пакетах. Ещё хотелось бы видеть на одном экране техническую информацию о пакете и тело. Кроме того, в этом представлении не видно, насколько позже или раньше уходит один запрос относительно другого. В этом нам поможет Sequence view.
Sequence view
Переключаем вкладку на Sequence и видим последовательность коннектов, в верхней части экрана будут появляться новые и новые подключения, обмен информацией не останавливается. Выбрав конкретное подключение, получим информацию о запросе и ответе для конкретного соединения на одном экране.
Необходимую техническую информацию о подключении выводим через колонки таблицы. Мне наиболее интересными кажутся: время начала запроса, используемый метод, код ответа, полный путь обращения, длительность соединения (или время получения ответа), размер пакета, IP-адрес отправителя, по которому выполняем сортировку, если к Charles подключено больше одного устройства.
Можно создать кастомную колонку по любому полю заголовков запроса/ответа. Например, рекламные SDK часто передают полезную информацию в заголовках ответа.
Для настройки нажимаем на заголовок таблицы ПКМ и выбираем New Custom Header Column. Указываем название заголовка.
Ставим галочку Focused и видим только те ручки, что ранее выбрали через Structure view.
Ещё одна классная фича — возможность обходиться без галочки Focused и делать фильтрацию с помощью регулярок. Для этого нужно нажать на Settings справа от строки фильтрации и поставить галочку тут:
Теперь, составив, например, такой фильтр, увидим тот же результат, как при использовании галочки Focused.
Анализируем результаты
Ещё раз зафиксируем, на что в общем случае стоит обратить внимание:
- При выполнении действия на клиенте с него уходит запрос по нужному URL.
- Время между действием и отправкой запроса.
- Соответствует ли метод запроса ожидаемому.
- В каком формате переданы данные серверу, не пусты ли значения.
- Не дублируется ли запрос.
- Вернулся ли ответ сервера за допустимое время, соответствуют ли код и тело ответа ожиданиям.
- Блокирующий ли запрос (важно для запросов на старте приложения).
- Отобразились ли полученные данные на клиенте (если применимо) за допустимое время.
В каких случаях стоит насторожиться и бежать к бэкендерам:
- запрос не завершается;
- возвращается неожиданный код ответа бэкенда;
- в ответе бэкенда возвращается 200 ОК, но в теле содержится ошибка;
- возвращается ошибочный код ответа от бэкенда (например, 500), но в теле ошибка отсутствует;
- мы не понимаем, что происходит.
Задача 2. Меняем API
Случается, что мобильным тестировщикам приходится проверять фичу на тестовом API, которое пока не задеплоено на продакшен. Можно попросить разработчиков добавить developer mode, в котором будет возможность изменить ручку API, но можно это сделать и без внесения изменений в код.
Итак, у нас есть URL тестовой среды, на которой можно протестировать фичу — https://api-1111.ifunny.mobi, и URL продового API — https://api.ifunny.mobi.
Charles позволяет решить эту задачу следующими способами.
Map Remote
С помощью Map Remote можно без СМС и регистрации выполнить переадресацию запросов с некоторого URL (Map From) на другой (Map To). Подменяем только хост, путь целиком или только параметры (в зависимости от задачи).
Настраиваем Map Remote для решения текущей задачи. Чтобы перейти в настройки Map Remote, выбираем Tools: Map Remote или для macOS (⌘⌥M). Шорткаты ускорят работу в Charles.
Примечание: Charles автоматически распарсит части URL при копировании и вставке. Вставляем URL в строку Host, нажимаем Tab. Protocol, Port, Path, Query заполнятся сами.
Rewrite
Rewrite — самый мощный механизм Charles. В коллекциях на текущем проекте порядка 30 наборов рерайтов (Rewrite sets) с десятками вложенных правил (Rewrite rules).
Для создания Rewrite нужно перейти в Tools -> Rewrite (или для macOS нажать — ⌘⌥R). Для добавления Rewrite set жмём на (1), ему можно задать название в поле (2). Rewrite sets могут быть ограничены набором хостов, на которых применяются правила. Если область действия правил (Location) не задать, то они будут применяться ко всем хостам. Для задания Location жмём на (3).
Чтобы добавить первое правило, нажимаем на (4). Появляется скромное окошко, обладающее большими возможностями.
Rewrite — это подмены: в заголовках (header rules), в пути (URL), в параметрах (query parameter rules) и в теле запроса или ответа (body rules).
Помимо подмен можно добавить или удалить новые заголовки, параметры запроса, когда это нужно. Для этого выбираем подходящее для задачи значение из выпадающего списка Тип (Type).
Для правила требуется указать область действия: запросы клиента (Request), ответы сервера (Response) или и те, и другие. Устанавливаем соответствующие чек-боксы.
Рассмотрим алгоритм применения Rewrite. Если указать маркер применения правила через блок Match, выполнится поиск этого значения в пакете, а затем замена на значение из блока Replace. Здесь и в некоторых других местах полезно использовать регулярные выражения, при необходимости — соответствующий чек-бокс. При пустом блоке Match замена применится везде, где можно. Заменится весь хост при типе Host или всё тело пакета при типе Body.
Ещё можно выбрать опцию «Подменить один раз» (Replace First), тогда Rewrite будет применён только по первому совпадению. Заполнение полей может оказаться недоступным для некоторых типов правил.
Для смены API подойдёт Type: Host. Нужное правило выглядит так:
Можно не прописывать Match, потому что указан Location, к другим хостам правило не применится, но Value пришлось бы указать целиком.
Задача 3. Проверяем нестандартные коды ответа
Кейсы, описанные в начале статьи, заставляют тестировщиков проверять получение и обработку ошибок. Здорово, когда пользователь понимает, что происходит, по ёмким нотификациям.
Прежде чем приступить к проверке, уточняем детали со стороны продукта и разработки:
- какие коды ошибок возвращает бэкенд;
- какая обработка ожидается при ошибке сервера: 500, 503;
- какая обработка ожидается при ошибках клиента: 403, 404;
- требуется ли повторить отправку запроса при получении ответа с ошибкой;
- должны ли уходить следующие запросы, пока не получен успешный ответ.

- Сделать редирект на URL, который отдаст нужную нам ошибку, но надо иметь список соответствующих URL.
- Универсальный способ решения этой задачи — через Rewrite с типом Response Status.
Создаём правило. Указываем в Replace нужный код ответа: - Для возвращения ошибок типа 403 можно использовать механизмы Block list (для macOS — ⌘⌥B), Allow list (для macOS — ⌘⌥W).
Block Lists, Allow Lists
Block List позволяет добавить URL, запросы к которым будут заблокированы путем разрыва соединения или возврата 403 кода ответа. Включаем так:
Allow list работает по обратной логике: указываем те URL, обращения к которым разрешены. Остальные соединения сбрасываются или возвращается 403 ошибка.
Задача 4. Безопасный способ подменить тело
Представьте, вы нашли баг: приложение падает при получении рекламного креатива. Сниффер включён, сессия сохранена.
Через время разработчику требуется воспроизвести ситуацию у себя, а рекламодатель не спешит возвращать ту же рекламу, что привела к ошибке. Что делать? Открываем сохраненную сессию и находим креатив.
Map Local
Для подмены ответа сервера целиком можно использовать Map Local (⌘⌥L). Это удобный инструмент, который позволяет заменить удалённый файл на тот, что хранится локально на машине. Указываем ручки, ответы к которым надо подменить, и выбираем файлы у себя в системе, предварительно сохранив их в нужном расширении/формате (json, xml и т.п., поддерживаются медиа и другие менее популярные форматы). В контексте представленного кейса нам надо откопать приводящий к проблеме креатив из сохранённой сессии, положить себе в папку и включить на него Map Local.
Здесь можно также воспользоваться Rewrite. Выбираем Type: Body, поле Match остаётся незаполненным, если заменяем тело целиком. Вставляем простыню с телом ответа в поле Value блока Replace, применяем.
Заменить определённую часть запроса/ответа через Rewrite также не представляет сложности.
Это полезно, когда мы хотим получить на клиенте какие-то значения, которые трудно сгенерировать на тестовой или продакшен-среде. Для этого в поле Match указываем, какую пару «ключ-значение» ответа API мы ищем, а в Replace — на какую пару подменяем.
Задача 5. Таймауты и троттлинг.
Плох тот тестировщик, который тестирует свое приложение только в условиях мощного офисного WiFi, находясь в одной сети с серверами. Как можно выяснить, что потери и задержки не нарушают usability для пользователя, или обнаружить, что при получении таймаута приложение не может восстановиться?
Настройки троттлинга (⇧⌘T) в Charles выглядят так :
Подбираем те, которые превратят любимое приложение в тыкву, а для тестирования таймаутов используем Breakpoints (⇧⌘K).
Примечание: Пользуйтесь возможностью включить троттлинг только на определённых хостах.
Брейкпоинты в Charles — это очень крутая штука. Информация о них будет в первых результатах поисковой выдачи по запросу «как подменить ХХХ в Charles». Их действительно можно использовать вместе или вместо Rewrite, но для подмен они не очень подходят.
Breakpoints работают так же, как бряки в коде. Получили совпадение по запросу или ответу — остановили выполнение, можем внести изменения в любую часть пакета. При этом подмена применится только на один пакет — нет повторяемости. Можно выйти за таймаут, пока выполняешь изменения. Другие способы подмены лишены этих ограничений.
Из неочевидного
Оптимизируем Rewrite
Что ещё здесь интересного? Активных правил в наборе может быть несколько, они применяются последовательно, сверху вниз. Значит, одно и то же место может изменяться несколько раз подряд.
Если есть какая-то структура, которая должна принимать несколько вариантов значений в зависимости от необходимости, то можно сделать следующее:
- Берём структуру, которую хотим подменить.
- Выносим её в переменную.
- Создаём набор правил по замене этой переменной на нужные тестовые структуры.
Например, приложение использует некоторое количество ID для получения рекламы. Мы хотим их все подменять то на один тестовый ID, то на другой. Здесь сначала все ID будут заменены на your_var, а your_var будет следом заменено в зависимости от простановки чек-боксов.
Если включить оба чек-бокса из примера одновременно, то вторая подмена уже не применится.
Примечание 1: никто нас не ограничивает в сложности используемых подмен, регулярных выражений, но некоторые нюансы типа того, что выше, могут затруднять отладку или привести к ненужному срабатыванию правил.
Примечание 2: «Я всё делаю правильно, но Rewrite не работает».
- Проверяем, что Rewrite был применён к выбранному пакету, информация об этом в явном виде есть во вкладке Overview и Notes:

- Включаем логи в Charles в окне Rewrite:

Window -> Error Log может содержать полезную информацию. Например, как ниже: проверяю правило, найден матч, выполнен Rewrite.
- Убедимся, что другие наборы Rewrite не переписывают поверх наше правило. Отмеченные чек-боксами наборы также применяются друг за другом, сверху вниз, как и правила внутри набора.
- Проверяем Location.
- Убедимся, что все чек-боксы на своих местах.
- Убедимся, что не произошло ошибки при копировании-вставке. Известный баг Charles на macOS: при копировании в буфер обмена при раскладке клавиатуры, отличной от английской, данные в буфере задваиваются и вставляется два значения вместо одного.
Auto save
Один из недостатков Charles — утечки памяти, возникающие при продолжительной записи сессии. Чтобы избежать утечек, необходимо регулярно очищать активную сессию. Из-за этого возникают ситуации, когда вы случайно очистили нужную сессию. Чтобы защититься, автоматизируем сохранение сессий.
Перейдём в Tools -> Auto Save (⌘⌥A), выберем интервал сохранения сессий и путь для сохранения chls-файлов. Теперь через каждую минуту сессия будет сохраняться локально, а затем очищаться в Charles без дополнительных действий с вашей стороны.
Mirror
Еще одна не самая очевидно полезная функция — Mirror (⌘⌥I). Эта фича позволяет автоматически сохранять все ответы, возвращаемые в Charles. Они раскладываются локально в такой же иерархии, как на сервере. Если внезапно случился даунтайм на бэкенде, отвалилась тестовая среда и так далее, у вас есть готовые моки для Map Local.
На этом всё. Я постаралась раскрыть возможности Charles Proxy для тестировщиков мобильных (и не только) приложений в разрезе тех задач, которые мы решаем в FunСorp. Если какие-то функции, которые вы используете, остались за бортом, пожалуйста, напишите об этом в комментариях.
И помните: хороший тестировщик клиент-серверных приложений всегда прикладывает к багу сессию из любимого сниффера.
- тестирование по
- тестирование
- qa mobile
- тестирование мобильных приложений
- qa
Разработка приложений Android с помощью React Native
Это руководство поможет вам начать работу с React Native в Windows для создания кросс-платформенных приложений, которые будут работать на устройствах Android.
Обзор
React Native — это платформа для разработки мобильных приложений с открытым кодом, созданная Facebook. Она используется для разработки приложений для Android, iOS, Интернета и UWP (Windows). Решение предоставляет собственные элементы управления пользовательского интерфейса и полный доступ к собственной платформе. Для работы с React Native требуется понимание основ JavaScript.
Начало работы с React Native путем установки требуемых средств
- Установите Visual Studio Code (или любой другой редактор кода).
- Установите Android Studio для Windows. По умолчанию Android Studio устанавливает последнюю версию пакета SDK для Android. React Native требует пакета SDK для Android 6.0 (Marshmallow) или более поздней версии. Мы рекомендуем использовать последнюю версию пакета SDK.
- Создайте пути к переменным среды для пакетов SDK для Java и Android:
- В меню поиска Windows введите: «изменить системные переменные среды». Откроется окно Свойства системы.
- Выберите элемент Переменные среды и нажмите кнопку Создать в разделе Пользовательские переменные.
- Введите имя и значение переменной (путь). Ниже приведены пути по умолчанию для пакетов SDK для Java и Android. Если вы выбрали определенное расположение для установки пакетов SDK для Java и Android, обязательно обновите пути к переменной соответствующим образом.
- JAVA_HOME: C:\Program Files\Android\Android Studio\jre\bin
- ANDROID_HOME: C:\Users\имя_пользователя\AppData\Local\Android\Sdk

Кроме того, вы можете установить и использовать Терминал Windows для работы с удобным для вас интерфейсом командной строки (CLI), а также Git для управления версиями. Java JDK поставляется с Android Studio версии 2.2 и выше, но, если вам нужно обновить JDK отдельно от Android Studio, используйте установщик Windows x64.
Создание нового проекта с помощью React Native
- Используйте npx, средство запуска пакетов, которое устанавливается вместе с npm, чтобы создать новый проект React Native из командной строки Windows, PowerShell, Терминала Windows, или встроенного терминала в (Вид > Встроенный терминал).
npx react-native init MyReactNativeApp
Если вы хотите запустить новый проект с определенной версией React Native, можно использовать —version аргумент. Сведения о версиях React Native см. в разделе «Версии React Native».
npx react-native@X.XX.X init --version X.XX.X
cd MyReactNativeApp

npx react-native run-android


Примечание. Если вы используете новую установку Android Studio и еще не разрабатывали приложения Android, при запуске приложения на этапе принятия лицензий для пакета SDK для Android в командной строке могут возникнуть ошибки. Например, «Предупреждение: лицензия на пакет android SDK Platform 29 не принимается». Чтобы устранить эту проблему, можно нажать кнопку диспетчера пакетов SDK в Android Studio . Кроме того, вы можете перечислить и принять лицензии с помощью следующей команды, используя путь к расположению пакета SDK на компьютере.
C:\Users\[User Name]\AppData\Local\Android\Sdk\tools\bin\sdkmanager --licenses
> Edit >App.js to change this screen and then come back to see your edits. HELLO WORLD!

- В окне консоли средства увязки в пакеты Metro введите r.
- В эмуляторе устройства Android дважды коснитесь r на клавиатуре.
- Дважды встряхните физическое устройство Android, чтобы открыть меню отладки React Native, и выберите команду Reload (Перезагрузить).
Дополнительные ресурсы
- Разработка приложений для двойного экрана для Android и получение пакета SDK для устройства Surface Duo
- Добавление исключений Защитника Windows для повышения производительности
- Включение поддержки виртуализации для повышения производительности эмулятора
