Когда в проекте появляются сложные сценарии: нестабильный бэкенд, редкие ошибки, зависимость от внешних сервисов, классические инструменты тестирования могут тормозить. Любая правка требует участия сервера, а воспроизведение бага превращается в квест.
В этот момент прокси-инструменты вроде Proxyman начинают играть совсем другую роль. Это уже не просто «посмотреть запросы», а полноценный слой управления трафиком.
Меня зовут Станислав, я Test-инженер в KODE, в этой статье разберу, как использовать Proxyman Scripts не как вспомогательную фичу, а как инструмент автоматизации тестирования.
Где вообще здесь автоматизация
На первый взгляд скрипты в прокси выглядят как простая подмена ответа. Но по факту это точка, где вы можете:
-
вмешаться в любой сетевой вызов
-
изменить данные до того, как их увидит приложение
-
воспроизвести нужное состояние системы без участия бэкенда
То есть фактически вы получаете контролируемую «прослойку» между клиентом и сервером. И это меняет подход к тестированию: вместо «ждём, пока бэкенд починят» — эмулируем ответ; вместо «не можем воспроизвести баг» — собираем сценарий вручную; вместо «нужно поднять тестовый стенд» — делаем всё локально.
Как устроено выполнение скриптов
В Proxyman скрипты выполняются в двух точках:
-
onRequest— до отправки запроса -
onResponse— после получения ответа
Это не просто «хуки», а полноценные точки управления данными.
У вас есть доступ к объектам:
-
request -
response
И вы можете:
-
менять
body -
редактировать
headers -
добавлять комментарии
-
менять визуальное отображение запроса
Ключевой момент: изменения происходят до того, как данные попадут в приложение.
Для клиента это выглядит так, будто сервер вернул именно эти данные.
Скрипты в Proxyman находятся во вкладке Scripting → Script List (в верхней панели). Можно создать новый скрипт, задать ему имя и выбрать, будет ли он работать на запрос (onRequest) или на ответ (onResponse). Для каждого скрипта можно указать фильтр (например, только определённые URL или методы).
Рядом с каждым скриптом есть чекбокс. Когда он включён, скрипт активен. В редакторе скрипта есть отдельные чекбоксы для onRequest и onResponse — их можно включать/отключать независимо.

Полезные инструменты, для ускорения и частичной автоматизации процесса тестирования:
-
Использование переменных для подмены данных
Переменные помогают хранить значения, которые вы хотите подставить в ответ или запрос. Это удобно, когда нужно заменить большой блок данных (например, массив карт) или точечно изменить один параметр.
Когда это реально полезно
-
Фича ещё не реализована на бэке
Можно собрать UI и протестировать поведение заранее. -
Данные сложно получить
Например, редкий статус транзакции или особый тип ошибки. -
Нужно ускорить тестирование
Не дергать сервер каждый раз, а стабилизировать ответ.
Шаг 1: Определите переменную
В JavaScript переменная объявляется с помощью var, let или const. Внутри скрипта вы можете создать объект или массив, который будет имитировать данные.
Переменные:
-
var: Устаревший. Виден везде внутри функции (даже вне циклов/условий). Можно объявлять повторно.
-
let: Современный. Виден только внутри блока { } (например, внутри if или for).
-
const: Как let, но значение нельзя менять (кроме содержимого объектов и массивов).
// Пример: создаём переменную, которая будет имитировать массив cards данные карты и назовем ее cards_mock
var cards_mock = [{
"accountOpenDate": "2019-03-12",
"applePayAvailable": true,
"availableBalance": "2500",
"cardHolder": "TESTER QA",
"cardId": "100002556979",
"cardNoFinish": "7777",
"bnpl": {
"amount": {
"available": "1200",
"currency": "EUR",
"total": "2000"
}
}
},
{
"accountOpenDate": "2012-08-22",
"applePayAvailable": false,
"availableBalance": "1000",
"cardHolder": "TESTER QA2",
"cardId": "100002556997",
"cardNoFinish": "8888"
}];
Шаг 2: Подставьте переменную в ответ
Когда обрабатываете ответ (onResponse), у вас есть доступ к объекту response.body. Это тело ответа, которое сервер вернул приложению. Вы можете заменить его часть или полностью.
// Заменяем весь массив "cards" в ответе на нашу переменную
response.body["cards"] = cards_mock;
Получаем такую функцию, объявляем массив в переменную, после чего используем ее для подмены ответа. Можно использовать разные переменные и менять их в зависимости от условий.

Из всего ответа мы подменили только один массив, не затрагивая остальные данные.

Если нужно изменить только одно поле внутри существующего ответа, используйте путь к объекту и индексацию для массива:
// Меняем конкретное поле для второй карты в массиве
response.body["cards"][0]["availableBalance"] = "9999";


// Или более глубокое поле внутри первой карты в массиве
response.body["cards"][0]["bnpl"]["amount"]["available"] = "100";


Если вы работаете с response.body, убедитесь, что ответ действительно содержит JSON. Для XML или других форматов подход может отличаться.
Если подменяете данные в onRequest, используйте request.body (тело запроса).
Аналогично можно подменять значения для request.headers["X-New-Headers"] и request.queries["name"]
2. Условия if и else: основа сложных сценариев
Без условий скрипты превращаются в хаотичный набор подмен. С условиями — в инструмент сценарного тестирования.
Базовый синтаксис
if (условие) {
// что-то делаем, если условие истинно
} else {
// иначе делаем что-то другое
Пример 1: Проверка параметра в теле запроса
Запрос лимитов для валют, представьте, что в запросе есть параметр currency. Если он соответствует нужной валюте, мы хотим отдать заранее подготовленный ответ.
Вариант 1: Объявляем переменные и подставляем их в тело ответа в зависимости от запрошенной валюты
async function onResponse(context, url, request, response) {
// Определяем три возможных варианта ответа для RUB, EUR и любого другого значения
var bodyRub = {
"amountLimit": {
"maximum": "90000",
"minimum": "1"
}
};
var bodyEur = {
"amountLimit": {
"maximum": "1000",
"minimum": "1"
}
};
var bodyOther = {
"amountLimit": {
"maximum": "2000",
"minimum": "1"
}
};
// Проверяем тело запроса, а именно значение параметра currency
if (request.body.currency === "RUB") {
response.body = bodyRub; // Если запрос отправляется для валюты "RUB" - то подставляем переменную c лимитом для RUB
} else if (request.body.currency === "EUR") {
response.body = bodyEur; // Для EUR соответственно подставляем лимит EUR
} else {
response.body = bodyOther; // Для всех других значений валюты - подставляем переменную c общим лимитом
}
return response;
}



Все эти проверки работают автоматизированно в одном скрипте, поэтому не требуется каждый раз вмешиваться в подмену запроса или ответа.
Вариант 2:: Представленная выше схема показана для логики работы if/else, но данное решение можно реализовать и другим способом, более изящным (вставляем этот код вместо блока с условной логикой):
// Создаем объект-словарь с соотношением значений currency к переменной ответа
const currencyMap = {
RUB: bodyRub,
EUR: bodyEur
};
response.body = currencyMap[request.body.currency] || bodyOther;
//Теперь тело ответа будет подставлять соответствующую переменную со словаря, а в случае отсутствия в словаре - bodyOther
Вариант 3: Так-же можно обойтись и без переменных, если нам требуется подменить только одно значение максимального лимита:
async function onResponse(context, url, request, response) {
if (request.body.currency === "RUB") {
response.body["amountLimit"]["maximum"] = "90000"; // для RUB
} else if (request.body.currency === "EUR") {
response.body["amountLimit"]["maximum"] = "1000"; // для EUR
} else {
response.body["amountLimit"]["maximum"] = "2000"; // Другие валюты
}
return response;
}
Вариант 4: Лучшее из вариантов 2 и 3, в случае когда нужно подменить значение только одного параметра - создаем объект словарь со значением максимального лимита для каждой валюты:
async function onResponse(context, url, request, response) {
const limits = {
RUB: "90000",
EUR: "1000"
};
// Берем значение из словаря, если его нет — ставим "2000"
response.body.amountLimit.maximum = limits[request.body.currency] || "2000";
return response;
}
Как можно заметить вариантов решений множество, поэтому можно по разному подойти к решению необходимой задачи и автоматизировать процессы тестирования
Пример 2: Проверка URL
Часто нужно применять логику только к определённым эндпоинтам. Например, для всех запросов, которые содержат /api/v1/payments:
if (request.url.includes("/api/v1/payments")) {
// Здесь мы можем менять ответы для платёжных запросов
response.body["status"] = "success";
}
Пример 3: Проверка HTTP-метода
Разные методы (GET, POST, PUT) могут требовать разной обработки:
if (request.method === "POST") {
// Действия только для POST-запросов
console.log("Это POST-запрос");
}
Пример 4: Проверка статус-кода ответа
Если сервер вернул ошибку, можно покрасить запрос в красный цвет или изменить тело ответа:
if (response.statusCode >= 400) {
response.color = "red";
// Можно также подменить тело ответа, чтобы приложение не упало
response.body = { "error": "handled by script" };
}
3. Визуализация трафика: underrated-фича
Когда запросов сотни — смотреть их «в лоб» невозможно. Цветовая подсветка — это простой способ быстро находить нужные запросы в списке трафика. Например, можно выделить зелёным все успешные запросы из кэша, красным — ошибки, синим — запросы с определённым заголовком.
Это ускоряет анализ логов, снижает когнитивную нагрузку, помогает находить паттерны.
Чтобы установить цвет, в скрипте onResponse (или onRequest) присвойте свойству response.colorстроку с названием цвета.
response.color = "blue";
Доступные цвета: red, yellow, orange, green, blue, purple, gray.
Пример: подсветка запросов, которые пришли из кэша:
// Предположим, в запросе есть поле, запрашивающее данные из кэша
if (request.body.fromCache === true) {
response.color = "green";
}
Теперь запрос, который обращается к кэшу, можно отличить визуально:

Пример: подсветка ошибок
if (response.statusCode >= 400) {
response.color = "red";
}

В результате в окне списка запросов вы увидите цветной текст в строке запроса. Это помогает мгновенно оценить, какие запросы требуют внимания.
4. Вывод комментариев с данными из запроса или ответа
Одна из самых недооценённых возможностей. Комментарии позволяют отображать важную информацию прямо в списке запросов, не открывая детали. Чтобы их увидеть, нужно добавить колонку Comment в интерфейсе Proxyman (обычно клик правой кнопкой по заголовкам колонок → выбрать Comment).
Добавление комментария с фиксированным текстом
response.comment = "TEST";
Теперь в колонке Comment у этого запроса будет написано "TEST".

Комментарий с динамическими данными
Вы можете извлечь значение из тела запроса или ответа и поместить его в комментарий.
В onRequest:
async function onRequest(context, url, request) {
request.comment = request.body["name"];
}

В onResponse:
async function onResponse(context, url, request, response) {
response.comment = response.body["cards"][0]["availableBalance"];
}

Комментарии можно комбинировать из нескольких полей, например:
response.comment = "Status: " + response.statusCode + " | User: " + response.body.user.name;
Это спасает при анализе больших логов, поиске конкретных значений, отладке сложных сценариев.
5. Несколько скриптов: уже почти pipeline
Proxyman позволяет включить несколько скриптов одновременно. Они будут выполняться последовательно в том порядке, в котором расположены в списке (сверху вниз). Это удобно, когда у вас есть скрипт для общей подмены данных (например, валюты) и отдельные скрипты для специфических эндпоинтов.
Важные моменты
-
Порядок имеет значение. Если один скрипт изменяет response.body, а следующий скрипт рассчитывает на исходные данные, это может привести к неожиданным результатам. Учитывайте последовательность.
-
Нельзя использовать «Run as Mock API» для нескольких скриптов. Эта опция предназначена для имитации работы бэкенда без реального сервера. Если вы используете несколько скриптов, не включайте её, если не уверены в совместимости.
Пример настройки
-
Скрипт №1: подменяет валюту во всех ответах на EUR.
-
Скрипт №2: добавляет комментарий с ID пользователя.
-
Скрипт №3: подсвечивает ошибки красным.
Все они будут работать вместе, если не конфликтуют.
Типичная ошибка:
-
первый скрипт меняет response.body
-
второй ожидает старую структуру
Получаем баг, который сложно найти.
6. Глобальные переменные sharedState: состояние между запросами
Глобальные переменные позволяют обмениваться данными между разными скриптами. Например, один скрипт сохраняет токен авторизации из ответа, а другой скрипт использует этот токен в последующих запросах.
В Proxyman за глобальные переменные отвечает объект sharedState. Вы можете сохранить в него любое значение, а затем прочитать его в другом скрипте.
Сохранение значения
// В скрипте onResponse после успешного входа
sharedState.refreshTokenNC = response.body["refreshToken"];
Использование сохранённого значения
В другом скрипте (например, для обновления токена) мы можем подставить этот токен в тело запроса.
// В скрипте onRequest для обновления токена
request.body["refreshToken"] = sharedState.refreshTokenNC;
Чтобы глобальные переменные работали, нужно разрешить их использование. В интерфейсе Proxyman перейдите в Scripting → Advanced и убедитесь, что опция включена.

Не забывайте проверять существование переменной перед использованием:
if (sharedState.refreshTokenNC) {
request.body["refreshToken"] = sharedState.refreshTokenNC;
Это убережёт от ошибок, если скрипт выполнится раньше, чем переменная будет установлена.
Советы по отладке скриптов
Когда вы пишете скрипты, полезно видеть, что происходит внутри. Вот несколько способов отладки:
1. Используйте console.log
В Proxyman вывод console.log можно увидеть в окне Scripting → Console (или в отдельной вкладке Console). Добавляйте логи, чтобы проверить, что скрипт вообще выполняется и какие значения имеют переменные.
console.log("Скрипт сработал для URL: " + url);
console.log("Значение fromCache: " + request.body.fromCache);

Используйте try...catch
Чтобы скрипт не падал из-за ошибок (например, отсутствия поля), оборачивайте критичные участки в try-catch.
try {
response.body["cards"][0]["balance"] = "1000";
} catch (e) {
console.log("Ошибка при изменении баланса: " + e.message);
}
3. Проверяйте, что скрипт включён
Убедитесь, что чекбокс рядом со скриптом активен и что в самом скрипте включён onRequest или onResponse (в зависимости от того, что вы пишете).
Задержка ответа/запроса
В Proxyman Scripts можно на любом этапе добавить задержку к выполнению кода. Например, можно поставить задержку для ответа с сервера, чтобы успеть проанализировать отображение данных с кэша и отследить их обновление к реальным данным. Команда sleep(1000) указывает задержку, где 1000 = 1сек.
Пример:
if (request.body.fromCache === false) {
sleep(2000);
};
Proxyman Scripts — это гибкий инструмент, который превращает прокси-сервер в мощного помощника для тестирования. С помощью скриптов вы можете:
-
Визуально анализировать трафик — окрашивая запросы и добавляя комментарии.
-
Эмулировать сложные сценарии — подменяя данные в зависимости от условий.
-
Ускорять ручное тестирование — автоматизируя повторяющиеся действия.
Не бойтесь экспериментировать: пробуйте менять разные поля, смотрите, как реагирует приложение. Со временем вы сможете создавать сложные цепочки скриптов, которые помогут проверять даже самые запутанные сценарии.
Все возможности Proxyman описаны в статье.
Автор: APPKODE
