TGViewer
Сергей Озеранский Сергей Озеранский @sergeiozeranskii · 2.35K subscribers
Post #616 104
Еще немного про ускорения. На этот раз про тесты, а точнее про coverage (Python).

Библиотека coverage.py используется почти во всех проектах, где я работал, и де-факто стала стандартом для отчетов о покрытии тестами. Но я ни разу не видел, чтобы ее работу оптимизировали.

У coverage.py три ядра измерения: ctrace (C-реализация sys.settrace), pytrace (то же на чистом Python) и sysmon (на базе sys.monitoring, PEP 669, Python 3.12+). Ядро выбирается переменной COVERAGE_CORE или, начиная с coverage 7.9, настройкой [run] core.

Нас интересует sysmon. Разберем, почему он быстрее и когда его включать.

settrace вызывает trace-функцию на каждое выполнение каждой строки, хотя для покрытия достаточно знать, выполнялась ли строка хоть раз. sys.monitoring позволяет отключить событие после первого срабатывания, и дальше этот код работает без накладных расходов. По оценке автора coverage.py, для line coverage оверхед часто ниже 5%.

Пример из практики: Trail of Bits на тестах PyPI (Python 3.12, поверх `pytest-xdist`) ускорили прогон с 58 до 27 секунд. Замер сделан в 2024 году. На актуальных версиях coverage в конфигурации "3.12 + branch coverage" такого эффекта уже не будет, почему - ниже.

Но есть нюансы:

• На 3.12/3.13 sysmon не работает с branch coverage: при branch = true coverage выдает предупреждение и измеряет через ctrace, ускорения нет. На 3.14+ sysmon умеет измерять и ветки, так что branch coverage тоже ускоряется.
• concurrency = gevent / eventlet / greenlet и dynamic_context в конфиге: coverage переключается на ctrace.
• --cov-context=test в pytest-cov: переключения на ctrace нет, и контексты под sysmon теряются. До 7.15.3 это происходило без сообщений, сейчас с предупреждением.
• Плагины (Cython, django_coverage_plugin и другие) под sysmon не работают.
• Реализация молодая: исправления для sysmon выходили в 2025-2026 годах (ложные missing branches, KeyError на сложных условиях и except*, падения на Jinja-шаблонах). Держите coverage.py свежим.

Как проверить, что заработало
На 3.14+ sysmon выбран по умолчанию, при конфликтах coverage переключается на ctrace. coverage run --debug=core покажет, какое ядро реально используется и почему.

Как итог:

• 3.14+: ничего не менять, проверить через --debug=core.
• 3.12/3.13, только line coverage: включать.
• 3.12/3.13 с branch coverage: включать бессмысленно.
• Нужны контексты по тестам или плагины: sysmon не подходит.

Документация: coverage.readthedocs.io/en/latest/config.html#run-core
  • 👍 1
  • 🔥 1
  • 👏 1
More from @sergeiozeranskii
  1. Sep 24, 2026Обнаружил, что агенты Claude Code в разных сессиях умеют общаться между собой. У меня сейч…
  2. Sep 23, 2026Возьмем Python-сервис в Kubernetes. Как правило на старте контейнера может проявляться спа…
  3. Sep 23, 2026Сегодня случилось страшное. То, чего я никак не ожидал. За все годы на MacBook со мной так…
  4. Sep 17, 2026Я вот не понимаю, зачем люди идут в OSS и контрибьютят на отвали. Ценности в этом ноль для…
  5. Sep 17, 2026Помните про https://github.com/ozeranskii/httptap? Я писал о нем давно еще - > тут. Наклеп…
  6. Sep 17, 2026Поломали или у меня поломалось? Как у вас?
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →