Данный модуль представляет собой распределенную многоагентную систему симуляции и бенчмаркинга пользовательского опыта (UX). В основе проекта лежит реактивный подход на базе фреймворка Akka Actors, моделирующий одновременное поведение сотен независимых операторов на веб-странице с использованием механизмов вероятностных конечных автоматов.
Модуль агрегирует результаты когнитивно-моторной деятельности агентов, оценивает влияние временных задержек и таймаутов на успешность выполнения сценариев и генерирует комплексные аналитические HTML-отчеты.
- Многоагентная симуляция: Одновременный запуск сотен изолированных акторов-тестировщиков без блокировки потоков.
- Асинхронные таймеры высокой точности: Использование встроенных планировщиков Akка (
TimerScheduler) для имитации дискретных попыток поиска и фиксации таймаутов. - Стохастические сценарии: Моделирование человеческого поведения с помощью вероятностных переходов между состояниями.
- Автоматическая генерация отчетов: Автоматический сбор метрик, расчет Success Rate и экспорт данных в красивый адаптивный HTML-дашборд.
Система построена по иерархическому принципу обмена асинхронными сообщениями:
-
TesterActor— симулирует изолированного пользователя. Обладает внутренним состоянием, управляет таймерами высокой точности для повторных попыток взаимодействия с элементами интерфейса и отслеживает критический таймаут сессии (SearchTimeout). -
MonitoringActor— потокобезопасный коллектор результатов. Ожидает завершения работы фиксированного пула агентов ($N$ ), после чего перенаправляет сводные метрики на этап обработки. -
LoggerActor— осуществляет структурированное логирование результатов в консоль и рассчитывает агрегированный показатель Success Rate. -
StatisticActor— аналитический модуль. Выполняет парсинг HTML-шаблонов, рассчитывает распределение причин отказов и формирует финальный дашборд.
Поведение пользователя формализовано в виде стохастического автомата. Переходы между состояниями зависят от распределения вероятностей, заложенного в конфигурации. Ключевые состояния:
q0— начальное состояние.q1— состояние поиска веб-элемента.q2— состояние действия (клик).qf1— финальное состояние успеха.qf2— финальное состояние провала.
- Из состояния
q1(поиск) агент с вероятностью 70% может завершить тест ошибкой "Не нашел кнопку" (qf2) и с вероятностью 30% успешно перейти к клику (q2). - Из состояния
q2(клик) точное попадание (qf1) происходит в 95% случаев, а случайный промах (qf2) — в 5%.
По завершении симуляции в корне проекта генерируется файл ux_test_report.html, содержащий:
- Summary-карточки: Общее число запущенных агентов, процент успешных сессий, среднее время удержания и таймауты.
- Диаграмму распределения отказов: Группировка неудачных тестов по причинам (например, “Could not find button in time” vs “Click missed”).
-
Детализированную таблицу логирования: Результаты и финальное состояние автомата для каждого из
$N$ тестеров индивидуально.
Для запуска нагрузочного тестирования интерфейса инициализируйте граф состояний автомата и передайте его в TestSystem:
import org.usersim.automaton.State;
import org.usersim.automaton.AlgorithmBuilder;
import org.usersim.system.TestSystem;
public class Main {
public static void main(String[] args) {
// 1. Определяем узлы графа поведения оператора
State q0 = new State("q0", false);
State q1 = new State("q1", false);
State q2 = new State("q2", false);
State qf1 = new State("qf1", true); // Успех
State qf2 = new State("qf2", true); // Сбой
// 2. Конфигурируем стохастические переходы (алгоритмы поведения)
q0.addAlgorithm("start", new AlgorithmBuilder("start")
.addExistingState(q1, false, 1.0)
.probabilisticTransition()
.build());
q1.addAlgorithm("search", new AlgorithmBuilder("search")
.addExistingState(q2, false, 0.3)
.addExistingState(qf2, true, 0.7) // 70% шанс потерять элемент
.probabilisticTransition()
.build());
q2.addAlgorithm("click", new AlgorithmBuilder("click")
.addExistingState(qf1, true, 0.95) // 95% точность клика
.addExistingState(qf2, true, 0.05)
.probabilisticTransition()
.build());
// 3. Инициализируем симуляционную систему на 200 одновременных агентов
TestSystem system = new TestSystem(200, q0);
// 4. Запускаем тест с ограничением в 1 секунду на оператора
system.startTest(1);
}
}