Как стать автором
Обновить

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

Уровень сложностиПростой
Время на прочтение2 мин
Количество просмотров856

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

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

Теги:
Хабы:
+2
Комментарии0

Публикации

Работа

Ближайшие события