Когда всё тормозит
Когда автотесты начинают тянуться как улитка, страдают все. CI медлит, разработчики косо смотрят на отчёты, а я вместо багов натыкаюсь на тайминги. Особенно это бесит в UI-тестах - там каждый шаг может тормозить, но с ходу это не видно.
В команде периодически всплывал один и тот же вопрос:
«Почему один и тот же сценарий утром идёт дольше, чем вечером?»
Захотелось простой утилиты:
Установила через pip
Подкинула лог
Получила список самых тормозных шагов
Никаких интеграций, серверов и плясок с бубном. Так появился Slowpoke Finder - маленькая CLI-утилита и библиотека для анализа логов автотестов. Кидаешь ему JSON или HAR - он вытаскивает шаги и показывает, какие из них реально тормозят.
С чего я начала
С самого начала знала: хочу CLI. Никакого UI, никаких API. Только терминал, скорость и минимум лишнего.
CLI я сделала на typer - он лёгкий, работает на type hints и почти не требует обвязки.
Упаковку проекта доверила poetry - люблю, когда всё по красоте: зависимости, версии, публикация.
Подключила pre-commit с ruff
, black
, mypy
- чтобы не отвлекаться на стилистику по ходу.
Архитектура
Я сразу поняла, что хочу поддержку разных форматов логов. И не хотела лепить огромный if format == ..., который разрастётся на 200 строк.
Сделала проще:
BaseParser через Protocol. Реестр registry и простой декоратор @register("название")
# registry.py
_registry = {}
def register(name: str):
def decorator(cls):
_registry[name] = cls()
return cls
return decorator
def get(format_name: str):
if format_name not in _registry:
raise ValueError(f"Unknown format: {format_name}")
return _registry[format_name]
Теперь каждый парсер регистрируется сам, и я могу легко расширять поддержку новых форматов.
Поддержка разных форматов
Первой добавила поддержку:
Playwright JSON - всё просто: список actions со startTime и endTime.
Selenium - и вот тут всё веселье: HAR, seleniumEvents, массивы в корне, разные ключи.
Каждый раз лог может прийти в новом виде - я сделала обработку всех популярных кейсов. Сначала была мысль - а может, определять формат автоматически? Но быстро отказалась: в HAR может быть что угодно, actions встречается не только у Playwright.
Так что решение простое и надёжное - пусть пользователь явно указывает --format
.
Оптимизация
Когда базовая логика работала, начала думать про производительность.
Сначала делала всё по классике:
top_steps = sorted(steps, key=lambda s: s.duration, reverse=True)[:top]
Явно не самый лучший вариант... Заменила на heapq:
import heapq
top_steps = heapq.nlargest(top, steps, key=lambda s: s.duration)
Почти в два раза быстрее. Особенно на больших логах - а я проверяла:
HAR-файл с 1 000 000 шагов
Обработка заняла 7 секунд
Память осталась в пределах разумного
Чтобы не хранить всё в памяти, в будущем планирую сделать парсинг через yield - шаги будут поступать потоком.
Что хочу добавить дальше
Сейчас Slowpoke Finder - это MVP. Он уже помогает экономить время и вылавливать реальные проблемы.
Но идей по развитию много:
HTML и Markdown отчёты
Поддержка JUnit, Cypress, CSV
Pre-commit hook и GitHub Action
Интеграция с Grafana / Plotly
Прямая работа с pytest и allure-cli
Если ты используешь Playwright, Selenium или Allure - попробуй мой Slowpoke Finder. Не хватает формата? Открой issue или пришли PR.
А если всё понравилось - звёздочка на GitHub всегда поднимает настроение :-) Ссылочка не репо проекта