Дополнительные действия
Elena (обсуждение | вклад) Нет описания правки |
Oagapov (обсуждение | вклад) Нет описания правки |
||
| (не показано 10 промежуточных версий 2 участников) | |||
| Строка 1: | Строка 1: | ||
=== Общее описание === | |||
'''Тестировщик''' — это приложение, предназначенное для: | |||
* Генерации тестовых данных для различных классов системы; | |||
* Нагрузочного и функционального тестирования; | |||
* Имитации работы реальных бизнес-процессов (call-центры, кампании, операторы); | |||
* Создания демонстрационных данных для презентаций и тестирования интерфейсов; | |||
'''Ключевые возможности:''' | |||
Откройте вкладку Генераторы данных. Импортируйте приложенный файл Генераторы данных.json. | * Множественные типы операций: добавление, изменение, удаление, импорт, очистка; | ||
* Контроль скорости генерации: через паузы (milliseconds) или CPS (calls per second); | |||
* Гибкая конфигурация данных: JSON-based с поддержкой случайных значений, диапазонов, параметров. | |||
Приложение ''Тестировщик'' полезно использовать для генерации случайных данных в продуктовом слое платформы. Что может быть полезно для понимания работы отчетов и дашбордов системы, а также разработки собственных. | |||
=== Быстрый старт === | |||
Запустите приложение ''Тестировщик'' с рабочего стола платформы. Приложение доступно для пользователей с ролью ''tester_admin''. | |||
Откройте вкладку Генераторы данных. Импортируйте приложенный файл [https://wiki.era-platform.ru/images/c/cf/%D0%93%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85.json Генераторы данных.json]. | |||
Название каждого скрипта отражает его функциональность. | Название каждого скрипта отражает его функциональность. | ||
| Строка 17: | Строка 31: | ||
===== 2. Генерация годовых архивов. ===== | ===== 2. Генерация годовых архивов. ===== | ||
[[Файл:Сгенерированные данные.png|мини|Сгенерированные данные]] | [[Файл:Сгенерированные данные.png|мини|Сгенерированные данные]] | ||
Откройте скрипт '''2.1. Генерация архива звонков'''. Отредактируйте при необходимости период времени, за который необходима генерация архива. Значения | Откройте скрипт '''2.1. Генерация архива звонков'''. Отредактируйте при необходимости период времени, за который необходима генерация архива. Значения "from": "2026-01-01" и "to": "2026-12-31". | ||
Обратите внимание, что указать период необходимо в | Обратите внимание, что указать период необходимо в нескольких местах: для входящих и исходящих звонков. | ||
Запустите скрипт и убедитесь, что архив звонков содержит случайный набор данных. Для этого запустите приложение «Отчеты» и перейдите во вкладку «Звонки — Завершенные». Используйте быстрые фильтры («Сегодня», «Вчера», «Неделя», «Месяц» и «Год»). | Запустите скрипт и убедитесь, что архив звонков содержит случайный набор данных. Для этого запустите приложение «Отчеты» и перейдите во вкладку «Звонки — Завершенные». Используйте быстрые фильтры («Сегодня», «Вчера», «Неделя», «Месяц» и «Год»). | ||
| Строка 46: | Строка 58: | ||
Для того чтобы полностью остановить все скрипты и освободить оперативную память, перезапустите продуктовый слой. Для этого в приложении «Настройки» откройте вкладку «Микросервисы» и для микросервиса platform_super_macro установите флаг «Выключен». Через несколько секунд верните флаг в исходное состояние. | Для того чтобы полностью остановить все скрипты и освободить оперативную память, перезапустите продуктовый слой. Для этого в приложении «Настройки» откройте вкладку «Микросервисы» и для микросервиса platform_super_macro установите флаг «Выключен». Через несколько секунд верните флаг в исходное состояние. | ||
=== Типы генераторов === | === Типы генераторов === | ||
| Строка 95: | Строка 93: | ||
==== 2. edit (Изменение) ==== | ==== 2. edit (Изменение) ==== | ||
Изменяет существующие записи, выбранные случайным образом. | Изменяет существующие записи, выбранные случайным образом. | ||
'''Особенности:''' | |||
* Требует наличия загруженных данных (через <code>filter</code> или без фильтра) | |||
* Выбирает случайную запись из кеша | |||
* Останавливается, если данных больше нет | |||
==== 3. delete (Удаление) ==== | |||
Удаляет существующие записи случайным образом. | |||
'''Особенности:''' | |||
* Похож на <code>edit</code> , но удаляет записи | |||
* Автоматически останавливается при отсутствии данных | |||
==== 4. import (Импорт) ==== | |||
Импортирует предопределенный массив данных за один раз. | |||
'''Пример конфигурации:'''<syntaxhighlight lang="json"> | |||
{ | |||
"kind": "import", | |||
"className": "callcenter/outbound/Campaigns", | |||
"totalCount": 1, | |||
"values": [ | |||
{ | |||
"id": "campaign_auto1_uuid", | |||
"name": "Автообзвон 1", | |||
"kind": "auto" | |||
}, | |||
{ | |||
"id": "campaign_auto2_uuid", | |||
"name": "Автообзвон 2", | |||
"kind": "auto" | |||
} | |||
] | |||
} | |||
</syntaxhighlight> | |||
==== 5. clear (Очистка) ==== | |||
Удаляет '''ВСЕ''' данные указанного класса. | |||
'''ВНИМАНИЕ''': Необратимая операция! | |||
'''Пример конфигурации:'''<syntaxhighlight lang="json"> | |||
{ | |||
"kind": "clear", | |||
"className": "callcenter/connections/CurrentConnections", | |||
"totalCount": 1 | |||
} | |||
</syntaxhighlight> | |||
==== 6. action (Вызов метода) ==== | |||
Вызывает метод сервиса с заданными параметрами. | |||
'''Пример конфигурации:'''<syntaxhighlight lang="json"> | |||
{ | |||
"kind": "action", | |||
"serviceName": "callcenter.HolderService", | |||
"methodName": "makeCall", | |||
"totalCount": 100, | |||
"cps": 5, | |||
"values": { | |||
"phoneNumber": { | |||
"from": "9211111111", | |||
"to": "9219999999" | |||
} | |||
} | |||
} | |||
</syntaxhighlight>'''Возвращает статистику:''' | |||
* Время выполнения запросов | |||
* Время выполнения действий | |||
* Min/Max/Avg значения | |||
==== 7. commandline (Командная строка) ==== | |||
Выполняет системные команды. | |||
'''Пример конфигурации:'''<syntaxhighlight lang="json"> | |||
{ | |||
"kind": "commandline", | |||
"totalCount": 10, | |||
"values": "echo 'Test command $random3'" | |||
} | |||
</syntaxhighlight>'''Доступные переменные:''' | |||
* <code>$random1</code> ... <code>$random7</code> — случайные числа разной длины | |||
* <code>$provider.name</code> — данные провайдеров | |||
=== Конфигурация генераторов === | |||
'''Синтаксис values (значений)''' | |||
==== 1. Простые значения ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"status": "active", | |||
"priority": 5 | |||
} | |||
</syntaxhighlight> | |||
==== 2. Случайный выбор из массива ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"direction": [ | |||
"in", | |||
"out" | |||
], | |||
"result": [ | |||
"success", | |||
"fail", | |||
"busy", | |||
"noanswer" | |||
] | |||
} | |||
</syntaxhighlight> | |||
==== 3. Диапазоны чисел ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"duration": { | |||
"from": 0, | |||
"to": 65 | |||
}, | |||
"age": { | |||
"from": 18, | |||
"to": 600 | |||
} | |||
} | |||
</syntaxhighlight> | |||
==== 4. Временные диапазоны ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"timeStart": { | |||
"from": "2024-01-01T00:00:00", | |||
"to": "2024-12-31T23:59:59" | |||
} | |||
} | |||
</syntaxhighlight>'''Специальное значение:'''<syntaxhighlight lang="json"> | |||
{ | |||
"timeStart": { | |||
"from": "today", | |||
"to": "today" | |||
} | |||
} | |||
</syntaxhighlight>Генерирует время в пределах ±24 часа от текущего момента. | |||
==== 5. Рабочее время и будни ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"callTime": { | |||
"from": "$param.from_time", | |||
"to": "$param.to_time", | |||
"worktime": true, | |||
"weekday": true | |||
} | |||
} | |||
</syntaxhighlight> | |||
==== 6. Параметры ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"campaign_id": "$param.campaign_auto1_id", | |||
"startDate": "$param.from_time" | |||
} | |||
</syntaxhighlight>'''ВАЖНО:''' В массивах параметры не работают напрямую! Используйте <code>expressionKind</code> :<syntaxhighlight lang="json"> | |||
{ | |||
"campaign_id": { | |||
"expressionKind": "code", | |||
"code": "return $params.campaign_auto1_id;" | |||
} | |||
} | |||
</syntaxhighlight> | |||
==== 7. Встроенные функции ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"domain": "$$$CurrentDomain$$$", | |||
"createdAt": "now()", | |||
"lastActivity": "lasthour()" | |||
} | |||
</syntaxhighlight> | |||
* <code>now()</code> — текущий timestamp▸ | |||
* <code>lasthour()</code> — случайное время за последний час | |||
* <code>$$$CurrentDomain$$$</code> — текущий домен сессии | |||
==== 8. Ссылки на другие сущности (random_id) ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"user_id": { | |||
"random_id": "platform/Users" | |||
}, | |||
"queue_id": { | |||
"random_id": "callcenter/acd/ACDQueues" | |||
} | |||
} | |||
</syntaxhighlight>Выбирает случайный ID из указанного класса. | |||
==== 9. Код JavaScript (expressionKind) ==== | |||
Для сложных вычислений:<syntaxhighlight lang="json"> | |||
{ | |||
"fullPhone": { | |||
"expressionKind": "code", | |||
"code": "return '7' + GlobalUtils.randomRange(9000000000, 9999999999);" | |||
}, | |||
"customId": { | |||
"expressionKind": "code", | |||
"code": "return GlobalUtils.generateUuid();" | |||
}, | |||
"calculatedValue": { | |||
"expressionKind": "code", | |||
"code": "return this.field1 + this.field2 * 100;" | |||
} | |||
} | |||
</syntaxhighlight>'''Доступный контекст:''' | |||
* <code>this</code> — текущий объект с уже заполненными полями | |||
* <code>index</code> — номер итерации (1, 2, 3...) | |||
* <code>$params</code> — объект со всеми параметрами | |||
* <code>GlobalUtils</code> — утилиты платформы | |||
==== 10. Вложенные объекты ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"sideA": { | |||
"kind": "inner", | |||
"display": { | |||
"from": "100", | |||
"to": "200" | |||
}, | |||
"user_id": { | |||
"random_id": "platform/Users" | |||
} | |||
}, | |||
"sideB": { | |||
"kind": "outer", | |||
"display": { | |||
"from": "9211111111", | |||
"to": "9219999999" | |||
} | |||
} | |||
} | |||
</syntaxhighlight>'''Управление скоростью генерации''' | |||
'''Способ 1: CPS (Calls Per Second)'''<syntaxhighlight lang="json"> | |||
{ | |||
"cps": 2, | |||
"totalCount": 172800, | |||
"_comment": "2 CPS × 86400 секунд (24 часа)" | |||
} | |||
</syntaxhighlight>'''Формула:'''<syntaxhighlight lang="json"> | |||
totalCount = CPS × duration_in_seconds | |||
</syntaxhighlight>Для 24 часов: <code>totalCount = CPS × 86400</code> | |||
'''Способ 2: Pause (миллисекунды)'''<syntaxhighlight lang="json"> | |||
{ | |||
"pause": 500, | |||
"totalCount": 1000, | |||
"_comment": "pause = 500 мс (0.5 секунды между операциями)" | |||
} | |||
</syntaxhighlight> | |||
=== Примеры использования === | |||
==== Пример 1: Генерация архивных звонков 24/7 ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"name": "Archive Connections - Incoming", | |||
"kind": "add", | |||
"className": "callcenter/connections/ArchiveConnections", | |||
"totalCount": 86400, | |||
"cps": 1, | |||
"interval": { | |||
"from": "$param.from_time", | |||
"to": "$param.to_time" | |||
}, | |||
"values": { | |||
"direction": "in", | |||
"duration": { | |||
"from": 10, | |||
"to": 600 | |||
}, | |||
"durationWait": [1, 2, 3, 4, 5], | |||
"durationTalk": { | |||
"from": 10, | |||
"to": 300 | |||
}, | |||
"durationHold": [0, 15, 25, 35], | |||
"timeStart": { | |||
"from": "$param.from_time", | |||
"to": "$param.to_time", | |||
"worktime": true, | |||
"weekday": true | |||
}, | |||
"sideA": { | |||
"kind": "outer", | |||
"display": { | |||
"from": "9211111111", | |||
"to": "9219999999" | |||
} | |||
}, | |||
"sideB": { | |||
"kind": "inner", | |||
"display": { | |||
"from": "100", | |||
"to": "200" | |||
}, | |||
"user_id": { | |||
"random_id": "platform/Users" | |||
} | |||
}, | |||
"stopside": ["a", "b"] | |||
} | |||
} | |||
</syntaxhighlight> | |||
==== Пример 2: Текущие звонки с жизненным циклом ==== | |||
<syntaxhighlight lang="json"> | |||
[ | |||
{ | |||
"name": "Current Connections - ADD", | |||
"kind": "add", | |||
"className": "callcenter/connections/CurrentConnections", | |||
"totalCount": 86400, | |||
"cps": 1, | |||
"values": { | |||
"status": "talk", | |||
"timeStart": "now()" | |||
} | |||
}, | |||
{ | |||
"name": "Current Connections - EDIT", | |||
"kind": "edit", | |||
"className": "callcenter/connections/CurrentConnections", | |||
"totalCount": 172800, | |||
"cps": 2, | |||
"values": { | |||
"status": [ | |||
"talk", | |||
"hold", | |||
"ringing" | |||
], | |||
"duration": { | |||
"from": 0, | |||
"to": 120 | |||
} | |||
} | |||
}, | |||
{ | |||
"name": "Current Connections - DELETE", | |||
"kind": "delete", | |||
"className": "callcenter/connections/CurrentConnections", | |||
"totalCount": 86400, | |||
"cps": 1 | |||
} | |||
] | |||
</syntaxhighlight> | |||
==== Пример 3: Импорт справочников ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"name": "Import Campaigns", | |||
"kind": "import", | |||
"className": "callcenter/outbound/Campaigns", | |||
"totalCount": 1, | |||
"values": [ | |||
{ | |||
"id": { | |||
"expressionKind": "code", | |||
"code": "return $params.campaign_auto1_id;" | |||
}, | |||
"name": "Автообзвон - Погашение задолженности", | |||
"kind": "auto", | |||
"status": "active" | |||
}, | |||
{ | |||
"id": { | |||
"expressionKind": "code", | |||
"code": "return $params.campaign_auto2_id;" | |||
}, | |||
"name": "Автообзвон - Информирование", | |||
"kind": "auto", | |||
"status": "active" | |||
} | |||
] | |||
} | |||
</syntaxhighlight> | |||
==== Пример 4: Генерация с использованием UUID ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"campaign_id": { | |||
"expressionKind": "code", | |||
"code": "return $params.campaign_auto1_id;" | |||
}, | |||
"call_id": { | |||
"expressionKind": "code", | |||
"code": "return GlobalUtils.generateUuid();" | |||
}, | |||
"contragent_id": { | |||
"expressionKind": "code", | |||
"code": "const base = 'contra_'; const suffix = (index % 1000).toString().padStart(4, '0'); return base + suffix;" | |||
} | |||
} | |||
</syntaxhighlight> | |||
==== Пример 5: Комплексная генерация для автообзвона ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"name": "Outbound Campaign Calls - Auto1", | |||
"kind": "add", | |||
"className": "callcenter/outbound/ArchiveCampaignCalls", | |||
"totalCount": 86400, | |||
"cps": 1, | |||
"interval": { | |||
"from": "$param.from_time", | |||
"to": "$param.to_time" | |||
}, | |||
"values": { | |||
"campaign_id": { | |||
"expressionKind": "code", | |||
"code": "return $params.campaign_auto1_id;" | |||
}, | |||
"contragent_id": { | |||
"expressionKind": "code", | |||
"code": "const num = (index % 1000).toString().padStart(4, '0'); return 'contra_' + num;" | |||
}, | |||
"phone": { | |||
"expressionKind": "code", | |||
"code": "return '7' + GlobalUtils.randomRange(9200000000, 9299999999);" | |||
}, | |||
"result": [ | |||
"success", | |||
"busy", | |||
"noanswer", | |||
"fail" | |||
], | |||
"attempts": { | |||
"from": 1, | |||
"to": 3 | |||
}, | |||
"duration": { | |||
"from": 0, | |||
"to": 300 | |||
}, | |||
"timeStart": { | |||
"from": "$param.from_time", | |||
"to": "$param.to_time", | |||
"worktime": true, | |||
"weekday": true | |||
}, | |||
"operator_id": { | |||
"random_id": "platform/Users" | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
=== Best Practices === | |||
==== 1. Организация генераторов ==== | |||
Группируйте по типам: | |||
* '''Setup''' (одноразовые): clear, import справочников | |||
* '''Archive''' (накопление): add с CPS 1-2 | |||
* '''Current''' (жизненный цикл): add → edit → delete | |||
'''Примерная структура:'''<syntaxhighlight lang="psql"> | |||
Setup/ | |||
├── 01_Clear_Current_Connections | |||
├── 02_Clear_Archive_Calls | |||
├── 03_Import_Campaigns | |||
└── 04_Import_Queues | |||
Archive/ | |||
├── Archive_Connections_IN | |||
├── Archive_Connections_OUT | |||
└── Archive_Campaign_Calls | |||
Current/ | |||
├── Current_Connections_ADD | |||
├── Current_Connections_EDIT | |||
├── Current_Connections_DELETE | |||
├── Current_Operators_ADD | |||
├── Current_Operators_EDIT | |||
└── Current_Operators_DELETE | |||
</syntaxhighlight> | |||
==== 2. Параметры ==== | |||
Создайте стандартный набор параметров:<syntaxhighlight lang="psql"> | |||
// Временные диапазоны | |||
from_time | |||
: "2024-01-01T00:00:00Z" | |||
to_time | |||
: "2024-12-31T23:59:59Z" | |||
// UUID для кампаний | |||
campaign_auto1_id | |||
: "00000000-0000-0000-0001-000000000001" | |||
campaign_auto2_id | |||
campaign_manual1_id | |||
: "00000000-0000-0000-0002-000000000002" | |||
: "00000000-0000-0000-0003-000000000003" | |||
// UUID для очередей | |||
queue_sales_id | |||
queue_support_id | |||
queue_vip_id | |||
: "00000000-0000-0000-1001-000000000001" | |||
: "00000000-0000-0000-1002-000000000002" | |||
: "00000000-0000-0000-1003-000000000003" | |||
// Контрагенты | |||
contragent_prefix | |||
contragent_count | |||
: "contra_ | |||
: "1000" | |||
</syntaxhighlight> | |||
==== 3. UUID Management ==== | |||
Используйте фиксированные UUID для связанных данных:<syntaxhighlight lang="psql"> | |||
// В Parameters | |||
campaign_auto1_id | |||
: "00000000-0000-0000-0001-000000000001" | |||
// В генераторах | |||
{ | |||
"campaign_id": { | |||
"expressionKind": "code" | |||
, | |||
"code": "return $params.campaign_auto1_id;" | |||
} | |||
} | |||
// Для массовых ID используйте паттерны | |||
{ | |||
"contragent_id": { | |||
"expressionKind": "code" | |||
, | |||
"code": "const num = (index % 1000).toString().padStart(4, | |||
'0'); return $params.contragent_prefix + num;" | |||
} | |||
} | |||
</syntaxhighlight> | |||
==== 4. CPS Planning ==== | |||
'''24-часовая генерация:'''<syntaxhighlight lang="psql"> | |||
Archive данные: CPS 1-2 | |||
Current ADD: CPS 1-2 | |||
Current EDIT: CPS 2-3 | |||
Current DELETE: CPS 1-2 | |||
Формула: totalCount = CPS × 86400 | |||
</syntaxhighlight>'''Примеры расчетов:'''<syntaxhighlight lang="psql"> | |||
CPS 1 → 86,400 операций/сутки | |||
CPS 2 → 172,800 операций/сутки | |||
CPS 5 → 432,000 операций/сутки | |||
CPS 10 → 864,000 операций/сутки | |||
</syntaxhighlight>'''Для разных интервалов:'''<syntaxhighlight lang="psql"> | |||
1 час: totalCount = CPS × 3,600 | |||
12 часов: totalCount = CPS × 43,200 | |||
7 дней: totalCount = CPS × 604,800 | |||
</syntaxhighlight> | |||
==== 5. Порядок запуска ==== | |||
<syntaxhighlight lang="psql"> | |||
1. Clear (очистка старых данных) | |||
└── Current классы (CurrentConnections, CurrentOperators) | |||
2. Import (справочники) | |||
├── Campaigns (кампании автообзвона) | |||
├── ACDQueues (очереди) | |||
├── Users (операторы, если нужны) | |||
└── SipUsers (SIP учетки) | |||
3. Archive ADD (исторические данные) | |||
├── ArchiveConnections (звонки) | |||
├── ArchiveSeances (сеансы) | |||
├── ArchiveCampaignCalls (звонки кампаний) | |||
└── ArchiveACDCalls (звонки очередей) | |||
4. Current ADD (текущие данные) | |||
├── CurrentConnections | |||
├── CurrentOperators | |||
└── CurrentCampaignCalls | |||
5. Current EDIT (изменения) | |||
├── CurrentConnections (статусы) | |||
└── CurrentOperators (статусы) | |||
6. Current DELETE (завершение) | |||
├── CurrentConnections | |||
└── CurrentCampaignCalls | |||
</syntaxhighlight> | |||
=== Расширенные техники === | |||
==== 1. Условная генерация ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"result": { | |||
"expressionKind": "code", | |||
"code": "const rand = Math.random(); if (rand < 0.7) return 'success'; else if (rand < 0.9) return 'busy'; else return 'noanswer';" | |||
} | |||
} | |||
</syntaxhighlight> | |||
==== 2. Связанные генераторы ==== | |||
<syntaxhighlight lang="json"> | |||
[ | |||
{ | |||
"name": "Create Contragents", | |||
"kind": "add", | |||
"className": "crm/Contragents", | |||
"_comment": "Генератор 1: создаёт контрагентов", | |||
"values": { | |||
"id": { | |||
"expressionKind": "code", | |||
"code": "return 'contra_' + index.toString().padStart(4, '0');", | |||
"_comment": "ID контрагента: contra_0000, contra_0001, ..." | |||
} | |||
} | |||
}, | |||
{ | |||
"name": "Create Calls", | |||
"kind": "add", | |||
"className": "callcenter/ArchiveCalls", | |||
"_comment": "Генератор 2: создаёт звонки и связывает их с контрагентами", | |||
"values": { | |||
"contragent_id": { | |||
"expressionKind": "code", | |||
"code": "const num = (index % 1000).toString().padStart(4, '0'); return 'contra_' + num;", | |||
"_comment": "Берём контрагента по индексу, циклически" | |||
} | |||
} | |||
} | |||
] | |||
</syntaxhighlight> | |||
==== 3. Генерация временных серий ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"timeStart": { | |||
"expressionKind": "code", | |||
"code": "const baseTime = new Date($params.from_time).getTime(); const interval = 60000; return baseTime + (index * interval);" | |||
} | |||
} | |||
</syntaxhighlight>Создает записи с интервалом в 1 минуту. | |||
==== 4. Взвешенное распределение ==== | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"priority": { | |||
"expressionKind": "code", | |||
"code": "const rand = Math.random(); if (rand < 0.6) return 'low'; else if (rand < 0.9) return 'medium'; else return 'high';" | |||
} | |||
} | |||
</syntaxhighlight>Распределение: 60% low, 30% medium, 10% high. | |||
=== Приложение: Полезные code snippets === | |||
'''Генерация UUID'''<syntaxhighlight lang="text"> | |||
GlobalUtils.generateUuid() | |||
</syntaxhighlight>'''Текущее время'''<syntaxhighlight lang="text"> | |||
GlobalUtils.nowTimeStamp() | |||
</syntaxhighlight>'''Форматирование строк'''<syntaxhighlight lang="text"> | |||
index .toString().padStart(4, '0') // "0001" , "0002" , ... | |||
</syntaxhighlight>'''Доступ к параметрам'''<syntaxhighlight lang="text"> | |||
$params parameter_name | |||
</syntaxhighlight>'''Доступ к текущим полям'''<syntaxhighlight lang="text"> | |||
this.fieldName | |||
</syntaxhighlight>'''Случайный выбор из массива'''<syntaxhighlight lang="text"> | |||
const = ['a' 'b' , , 'c']; | |||
items Math Math items length [ .floor( .random() * . )] | |||
</syntaxhighlight>'''Циклический выбор'''<syntaxhighlight lang="text"> | |||
const = ['a' 'b' , , [ %. ] | |||
items index items length 'c']; | |||
</syntaxhighlight> | |||
Текущая версия от 20:41, 5 февраля 2026
Общее описание
Тестировщик — это приложение, предназначенное для:
- Генерации тестовых данных для различных классов системы;
- Нагрузочного и функционального тестирования;
- Имитации работы реальных бизнес-процессов (call-центры, кампании, операторы);
- Создания демонстрационных данных для презентаций и тестирования интерфейсов;
Ключевые возможности:
- Множественные типы операций: добавление, изменение, удаление, импорт, очистка;
- Контроль скорости генерации: через паузы (milliseconds) или CPS (calls per second);
- Гибкая конфигурация данных: JSON-based с поддержкой случайных значений, диапазонов, параметров.
Приложение Тестировщик полезно использовать для генерации случайных данных в продуктовом слое платформы. Что может быть полезно для понимания работы отчетов и дашбордов системы, а также разработки собственных.
Быстрый старт
Запустите приложение Тестировщик с рабочего стола платформы. Приложение доступно для пользователей с ролью tester_admin.
Откройте вкладку Генераторы данных. Импортируйте приложенный файл Генераторы данных.json.
Название каждого скрипта отражает его функциональность.
1. Первичный импорт.

Откройте (JSON) скрипт 1.1. Импорт операторов. Значение поля (object) JSON содержит данные, которые будут загружены. Отредактируйте их при необходимости. Обратите внимание, что значения id должны быть уникальны. Запустите скрипт и убедитесь, что операторы появились в платформе.
Отредактируйте при необходимости и запустите скрипт 1.2. Импорт очередей. Убедитесь, что появились очереди в платформе.
Повторное выполнение скриптов возможно только после удаления операторов и очередей или изменения id на новые уникальные.
2. Генерация годовых архивов.

Откройте скрипт 2.1. Генерация архива звонков. Отредактируйте при необходимости период времени, за который необходима генерация архива. Значения "from": "2026-01-01" и "to": "2026-12-31".
Обратите внимание, что указать период необходимо в нескольких местах: для входящих и исходящих звонков.
Запустите скрипт и убедитесь, что архив звонков содержит случайный набор данных. Для этого запустите приложение «Отчеты» и перейдите во вкладку «Звонки — Завершенные». Используйте быстрые фильтры («Сегодня», «Вчера», «Неделя», «Месяц» и «Год»).
Повторите указанные выше действия для всех скриптов 2.X для постепенного заполнения платформы архивными данными.
Для очистки архивов используйте скрипты 0.X.
Обратите внимание, что некоторые скрипты содержат поля периода несколько раз.
3. Генерация данных на сегодня.
Используйте скрипты 3.X для заполнения данных на сегодняшний день. Это позволит заполнить данными дашборды, которые отображают данные за час и текущие сутки.
4. Генерация текущих данных.
Для того чтобы сгенерировать текущие данные по активности в контактного центре используйте скрипты 5.X.
Для того чтобы текущие данные изменялись во времени случайным образом используйте скрипты 6.X.
Текущие данные будут храниться в течение двух часов.
n.b. Для очистки данных остановите “долгоиграющие” генераторы и запустите скрипты очистки.
или
Для того чтобы полностью остановить все скрипты и освободить оперативную память, перезапустите продуктовый слой. Для этого в приложении «Настройки» откройте вкладку «Микросервисы» и для микросервиса platform_super_macro установите флаг «Выключен». Через несколько секунд верните флаг в исходное состояние.
Типы генераторов
1. add (Добавление)
Создает новые записи в указанном классе.
Пример конфигурации:
{
"kind": "add",
"className": "callcenter/connections/ArchiveConnections",
"totalCount": 86400,
"cps": 1,
"values": {
"direction": [
"in",
"out"
],
"duration": {
"from": 10,
"to": 600
},
"timeStart": {
"from": "$param.from_time",
"to": "$param.to_time"
}
}
}
Формула для 24-часовой генерации:
totalCount = CPS × 86,400 (секунд в сутках)
2. edit (Изменение)
Изменяет существующие записи, выбранные случайным образом.
Особенности:
- Требует наличия загруженных данных (через
filterили без фильтра) - Выбирает случайную запись из кеша
- Останавливается, если данных больше нет
3. delete (Удаление)
Удаляет существующие записи случайным образом.
Особенности:
- Похож на
edit, но удаляет записи - Автоматически останавливается при отсутствии данных
4. import (Импорт)
Импортирует предопределенный массив данных за один раз.
Пример конфигурации:
{
"kind": "import",
"className": "callcenter/outbound/Campaigns",
"totalCount": 1,
"values": [
{
"id": "campaign_auto1_uuid",
"name": "Автообзвон 1",
"kind": "auto"
},
{
"id": "campaign_auto2_uuid",
"name": "Автообзвон 2",
"kind": "auto"
}
]
}
5. clear (Очистка)
Удаляет ВСЕ данные указанного класса.
ВНИМАНИЕ: Необратимая операция!
Пример конфигурации:
{
"kind": "clear",
"className": "callcenter/connections/CurrentConnections",
"totalCount": 1
}
6. action (Вызов метода)
Вызывает метод сервиса с заданными параметрами.
Пример конфигурации:
{
"kind": "action",
"serviceName": "callcenter.HolderService",
"methodName": "makeCall",
"totalCount": 100,
"cps": 5,
"values": {
"phoneNumber": {
"from": "9211111111",
"to": "9219999999"
}
}
}
Возвращает статистику:
- Время выполнения запросов
- Время выполнения действий
- Min/Max/Avg значения
7. commandline (Командная строка)
Выполняет системные команды.
Пример конфигурации:
{
"kind": "commandline",
"totalCount": 10,
"values": "echo 'Test command $random3'"
}
Доступные переменные:
$random1...$random7— случайные числа разной длины$provider.name— данные провайдеров
Конфигурация генераторов
Синтаксис values (значений)
1. Простые значения
{
"status": "active",
"priority": 5
}
2. Случайный выбор из массива
{
"direction": [
"in",
"out"
],
"result": [
"success",
"fail",
"busy",
"noanswer"
]
}
3. Диапазоны чисел
{
"duration": {
"from": 0,
"to": 65
},
"age": {
"from": 18,
"to": 600
}
}
4. Временные диапазоны
{
"timeStart": {
"from": "2024-01-01T00:00:00",
"to": "2024-12-31T23:59:59"
}
}
Специальное значение:
{
"timeStart": {
"from": "today",
"to": "today"
}
}
Генерирует время в пределах ±24 часа от текущего момента.
5. Рабочее время и будни
{
"callTime": {
"from": "$param.from_time",
"to": "$param.to_time",
"worktime": true,
"weekday": true
}
}
6. Параметры
{
"campaign_id": "$param.campaign_auto1_id",
"startDate": "$param.from_time"
}
ВАЖНО: В массивах параметры не работают напрямую! Используйте expressionKind :
{
"campaign_id": {
"expressionKind": "code",
"code": "return $params.campaign_auto1_id;"
}
}
7. Встроенные функции
{
"domain": "$$$CurrentDomain$$$",
"createdAt": "now()",
"lastActivity": "lasthour()"
}
now()— текущий timestamp▸lasthour()— случайное время за последний час$$$CurrentDomain$$$— текущий домен сессии
8. Ссылки на другие сущности (random_id)
{
"user_id": {
"random_id": "platform/Users"
},
"queue_id": {
"random_id": "callcenter/acd/ACDQueues"
}
}
Выбирает случайный ID из указанного класса.
9. Код JavaScript (expressionKind)
Для сложных вычислений:
{
"fullPhone": {
"expressionKind": "code",
"code": "return '7' + GlobalUtils.randomRange(9000000000, 9999999999);"
},
"customId": {
"expressionKind": "code",
"code": "return GlobalUtils.generateUuid();"
},
"calculatedValue": {
"expressionKind": "code",
"code": "return this.field1 + this.field2 * 100;"
}
}
Доступный контекст:
this— текущий объект с уже заполненными полямиindex— номер итерации (1, 2, 3...)$params— объект со всеми параметрамиGlobalUtils— утилиты платформы
10. Вложенные объекты
{
"sideA": {
"kind": "inner",
"display": {
"from": "100",
"to": "200"
},
"user_id": {
"random_id": "platform/Users"
}
},
"sideB": {
"kind": "outer",
"display": {
"from": "9211111111",
"to": "9219999999"
}
}
}
Управление скоростью генерации
Способ 1: CPS (Calls Per Second)
{
"cps": 2,
"totalCount": 172800,
"_comment": "2 CPS × 86400 секунд (24 часа)"
}
Формула:
totalCount = CPS × duration_in_seconds
Для 24 часов: totalCount = CPS × 86400
Способ 2: Pause (миллисекунды)
{
"pause": 500,
"totalCount": 1000,
"_comment": "pause = 500 мс (0.5 секунды между операциями)"
}
Примеры использования
Пример 1: Генерация архивных звонков 24/7
{
"name": "Archive Connections - Incoming",
"kind": "add",
"className": "callcenter/connections/ArchiveConnections",
"totalCount": 86400,
"cps": 1,
"interval": {
"from": "$param.from_time",
"to": "$param.to_time"
},
"values": {
"direction": "in",
"duration": {
"from": 10,
"to": 600
},
"durationWait": [1, 2, 3, 4, 5],
"durationTalk": {
"from": 10,
"to": 300
},
"durationHold": [0, 15, 25, 35],
"timeStart": {
"from": "$param.from_time",
"to": "$param.to_time",
"worktime": true,
"weekday": true
},
"sideA": {
"kind": "outer",
"display": {
"from": "9211111111",
"to": "9219999999"
}
},
"sideB": {
"kind": "inner",
"display": {
"from": "100",
"to": "200"
},
"user_id": {
"random_id": "platform/Users"
}
},
"stopside": ["a", "b"]
}
}
Пример 2: Текущие звонки с жизненным циклом
[
{
"name": "Current Connections - ADD",
"kind": "add",
"className": "callcenter/connections/CurrentConnections",
"totalCount": 86400,
"cps": 1,
"values": {
"status": "talk",
"timeStart": "now()"
}
},
{
"name": "Current Connections - EDIT",
"kind": "edit",
"className": "callcenter/connections/CurrentConnections",
"totalCount": 172800,
"cps": 2,
"values": {
"status": [
"talk",
"hold",
"ringing"
],
"duration": {
"from": 0,
"to": 120
}
}
},
{
"name": "Current Connections - DELETE",
"kind": "delete",
"className": "callcenter/connections/CurrentConnections",
"totalCount": 86400,
"cps": 1
}
]
Пример 3: Импорт справочников
{
"name": "Import Campaigns",
"kind": "import",
"className": "callcenter/outbound/Campaigns",
"totalCount": 1,
"values": [
{
"id": {
"expressionKind": "code",
"code": "return $params.campaign_auto1_id;"
},
"name": "Автообзвон - Погашение задолженности",
"kind": "auto",
"status": "active"
},
{
"id": {
"expressionKind": "code",
"code": "return $params.campaign_auto2_id;"
},
"name": "Автообзвон - Информирование",
"kind": "auto",
"status": "active"
}
]
}
Пример 4: Генерация с использованием UUID
{
"campaign_id": {
"expressionKind": "code",
"code": "return $params.campaign_auto1_id;"
},
"call_id": {
"expressionKind": "code",
"code": "return GlobalUtils.generateUuid();"
},
"contragent_id": {
"expressionKind": "code",
"code": "const base = 'contra_'; const suffix = (index % 1000).toString().padStart(4, '0'); return base + suffix;"
}
}
Пример 5: Комплексная генерация для автообзвона
{
"name": "Outbound Campaign Calls - Auto1",
"kind": "add",
"className": "callcenter/outbound/ArchiveCampaignCalls",
"totalCount": 86400,
"cps": 1,
"interval": {
"from": "$param.from_time",
"to": "$param.to_time"
},
"values": {
"campaign_id": {
"expressionKind": "code",
"code": "return $params.campaign_auto1_id;"
},
"contragent_id": {
"expressionKind": "code",
"code": "const num = (index % 1000).toString().padStart(4, '0'); return 'contra_' + num;"
},
"phone": {
"expressionKind": "code",
"code": "return '7' + GlobalUtils.randomRange(9200000000, 9299999999);"
},
"result": [
"success",
"busy",
"noanswer",
"fail"
],
"attempts": {
"from": 1,
"to": 3
},
"duration": {
"from": 0,
"to": 300
},
"timeStart": {
"from": "$param.from_time",
"to": "$param.to_time",
"worktime": true,
"weekday": true
},
"operator_id": {
"random_id": "platform/Users"
}
}
}
Best Practices
1. Организация генераторов
Группируйте по типам:
- Setup (одноразовые): clear, import справочников
- Archive (накопление): add с CPS 1-2
- Current (жизненный цикл): add → edit → delete
Примерная структура:
Setup/
├── 01_Clear_Current_Connections
├── 02_Clear_Archive_Calls
├── 03_Import_Campaigns
└── 04_Import_Queues
Archive/
├── Archive_Connections_IN
├── Archive_Connections_OUT
└── Archive_Campaign_Calls
Current/
├── Current_Connections_ADD
├── Current_Connections_EDIT
├── Current_Connections_DELETE
├── Current_Operators_ADD
├── Current_Operators_EDIT
└── Current_Operators_DELETE
2. Параметры
Создайте стандартный набор параметров:
// Временные диапазоны
from_time
: "2024-01-01T00:00:00Z"
to_time
: "2024-12-31T23:59:59Z"
// UUID для кампаний
campaign_auto1_id
: "00000000-0000-0000-0001-000000000001"
campaign_auto2_id
campaign_manual1_id
: "00000000-0000-0000-0002-000000000002"
: "00000000-0000-0000-0003-000000000003"
// UUID для очередей
queue_sales_id
queue_support_id
queue_vip_id
: "00000000-0000-0000-1001-000000000001"
: "00000000-0000-0000-1002-000000000002"
: "00000000-0000-0000-1003-000000000003"
// Контрагенты
contragent_prefix
contragent_count
: "contra_
: "1000"
3. UUID Management
Используйте фиксированные UUID для связанных данных:
// В Parameters
campaign_auto1_id
: "00000000-0000-0000-0001-000000000001"
// В генераторах
{
"campaign_id": {
"expressionKind": "code"
,
"code": "return $params.campaign_auto1_id;"
}
}
// Для массовых ID используйте паттерны
{
"contragent_id": {
"expressionKind": "code"
,
"code": "const num = (index % 1000).toString().padStart(4,
'0'); return $params.contragent_prefix + num;"
}
}
4. CPS Planning
24-часовая генерация:
Archive данные: CPS 1-2
Current ADD: CPS 1-2
Current EDIT: CPS 2-3
Current DELETE: CPS 1-2
Формула: totalCount = CPS × 86400
Примеры расчетов:
CPS 1 → 86,400 операций/сутки
CPS 2 → 172,800 операций/сутки
CPS 5 → 432,000 операций/сутки
CPS 10 → 864,000 операций/сутки
Для разных интервалов:
1 час: totalCount = CPS × 3,600
12 часов: totalCount = CPS × 43,200
7 дней: totalCount = CPS × 604,800
5. Порядок запуска
1. Clear (очистка старых данных)
└── Current классы (CurrentConnections, CurrentOperators)
2. Import (справочники)
├── Campaigns (кампании автообзвона)
├── ACDQueues (очереди)
├── Users (операторы, если нужны)
└── SipUsers (SIP учетки)
3. Archive ADD (исторические данные)
├── ArchiveConnections (звонки)
├── ArchiveSeances (сеансы)
├── ArchiveCampaignCalls (звонки кампаний)
└── ArchiveACDCalls (звонки очередей)
4. Current ADD (текущие данные)
├── CurrentConnections
├── CurrentOperators
└── CurrentCampaignCalls
5. Current EDIT (изменения)
├── CurrentConnections (статусы)
└── CurrentOperators (статусы)
6. Current DELETE (завершение)
├── CurrentConnections
└── CurrentCampaignCalls
Расширенные техники
1. Условная генерация
{
"result": {
"expressionKind": "code",
"code": "const rand = Math.random(); if (rand < 0.7) return 'success'; else if (rand < 0.9) return 'busy'; else return 'noanswer';"
}
}
2. Связанные генераторы
[
{
"name": "Create Contragents",
"kind": "add",
"className": "crm/Contragents",
"_comment": "Генератор 1: создаёт контрагентов",
"values": {
"id": {
"expressionKind": "code",
"code": "return 'contra_' + index.toString().padStart(4, '0');",
"_comment": "ID контрагента: contra_0000, contra_0001, ..."
}
}
},
{
"name": "Create Calls",
"kind": "add",
"className": "callcenter/ArchiveCalls",
"_comment": "Генератор 2: создаёт звонки и связывает их с контрагентами",
"values": {
"contragent_id": {
"expressionKind": "code",
"code": "const num = (index % 1000).toString().padStart(4, '0'); return 'contra_' + num;",
"_comment": "Берём контрагента по индексу, циклически"
}
}
}
]
3. Генерация временных серий
{
"timeStart": {
"expressionKind": "code",
"code": "const baseTime = new Date($params.from_time).getTime(); const interval = 60000; return baseTime + (index * interval);"
}
}
Создает записи с интервалом в 1 минуту.
4. Взвешенное распределение
{
"priority": {
"expressionKind": "code",
"code": "const rand = Math.random(); if (rand < 0.6) return 'low'; else if (rand < 0.9) return 'medium'; else return 'high';"
}
}
Распределение: 60% low, 30% medium, 10% high.
Приложение: Полезные code snippets
Генерация UUID
GlobalUtils.generateUuid()
Текущее время
GlobalUtils.nowTimeStamp()
Форматирование строк
index .toString().padStart(4, '0') // "0001" , "0002" , ...
Доступ к параметрам
$params parameter_name
Доступ к текущим полям
this.fieldName
Случайный выбор из массива
const = ['a' 'b' , , 'c'];
items Math Math items length [ .floor( .random() * . )]
Циклический выбор
const = ['a' 'b' , , [ %. ]
items index items length 'c'];