Slowpoke Finder: как я сделала CLI-инструмент для анализа медленных шагов в автотестах

от автора

Когда всё тормозит

Когда автотесты начинают тянуться как улитка, страдают все. 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 всегда поднимает настроение 🙂 Ссылочка не репо проекта


ссылка на оригинал статьи https://habr.com/ru/articles/911952/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *