Skip to main content
Back to course
Pytest для джунов: Моки и интеграция
6 / 875%

pytest.ini: конфигурация для команды

20 минут

В вашей команде 5 разработчиков. Один запускает pytest -v, другой pytest --tb=short, третий pytest -m "not slow". Все получают разный вывод. Как унифицировать?

Цель: Научиться настраивать pytest через pytest.ini для всей команды.

Вы точно готовы?

Убедитесь, что умеете:

# Запускать pytest с опциями
pytest -v --tb=short --cov=src
 
# Использовать маркеры
@pytest.mark.slow
def test_something():
    pass

Если pytest опции непонятны — повторите предыдущие уроки.

Проблема: разные настройки у всех

Без pytest.ini

Разработчик 1:

pytest -v --tb=short tests/

Разработчик 2:

pytest --cov=src --cov-report=html tests/

Разработчик 3:

pytest -m "not slow" --maxfail=1 tests/

CI:

pytest --tb=no --cov=src --cov-fail-under=80

Проблемы:

  • ❌ Каждый запускает по-разному
  • ❌ Нужно помнить все опции
  • ❌ Сложно синхронизировать команду
  • ❌ Предупреждения о неизвестных маркерах
PytestUnknownMarkWarning: Unknown pytest.mark.slow

Решение: pytest.ini

Создание pytest.ini

# pytest.ini (в корне проекта)
 
[pytest]
# Где искать тесты
testpaths = tests
 
# Опции по умолчанию
addopts =
    -v
    --tb=short
    --strict-markers
 
# Регистрация маркеров
markers =
    slow: Медленные тесты (> 5 секунд)
    integration: Integration-тесты с внешними системами
    unit: Unit-тесты (изолированные)

Теперь все запускают просто:

pytest

✅ Все опции применяются автоматически!

testpaths: где искать тесты

[pytest]
testpaths = tests

Без testpaths:

# Pytest ищет тесты ВЕЗДЕ (медленно)
pytest  # Сканирует весь проект

С testpaths:

# Pytest ищет только в tests/ (быстро)
pytest  # Сканирует только tests/

✅ Быстрее discovery тестов!

Множественные директории:

[pytest]
testpaths =
    tests
    integration_tests

addopts: опции по умолчанию

[pytest]
addopts =
    -v                    # Verbose режим
    --tb=short            # Короткий traceback
    --strict-markers      # Ошибка на неизвестных маркерах
    --cov=src             # Coverage для src/
    --cov-report=term-missing

Теперь:

pytest  # Применяются все опции из addopts

Можно переопределить:

pytest --tb=long  # Переопределяет --tb=short из addopts

markers: регистрация маркеров

[pytest]
markers =
    slow: Медленные тесты (> 5 секунд)
    integration: Integration-тесты с внешними системами
    unit: Unit-тесты (изолированные)
    smoke: Smoke-тесты (быстрая проверка)
    api: Тесты API endpoints
    db: Тесты с БД

Без регистрации:

PytestUnknownMarkWarning: Unknown pytest.mark.slow

С регистрацией:

pytest  # Нет предупреждений ✅

Просмотр маркеров:

pytest --markers

Результат:

@pytest.mark.slow: Медленные тесты (> 5 секунд)
@pytest.mark.integration: Integration-тесты с внешними системами
@pytest.mark.unit: Unit-тесты (изолированные)
...

Практический пример: real-world pytest.ini

Для команды разработки

# pytest.ini
 
[pytest]
# === Где искать тесты ===
testpaths = tests
 
# === Опции по умолчанию ===
addopts =
    # Verbose режим
    -v
    # Короткий traceback (удобнее читать)
    --tb=short
    # Строгие маркеры (ошибка на неизвестных)
    --strict-markers
    # Coverage
    --cov=src
    --cov-report=term-missing
    --cov-report=html
    # Остановка на первой ошибке (для быстрой отладки)
    # --maxfail=1  # Раскомментировать для локальной разработки
 
# === Маркеры ===
markers =
    # По скорости
    slow: Медленные тесты (> 5 секунд)
    fast: Быстрые тесты (< 1 секунда)
 
    # По типу
    unit: Unit-тесты (изолированные)
    integration: Integration-тесты с внешними системами
    e2e: End-to-end тесты (полный цикл)
 
    # По зависимостям
    requires_db: Требует PostgreSQL
    requires_redis: Требует Redis
    requires_network: Требует интернет
 
    # По функциональности
    api: Тесты API endpoints
    auth: Тесты аутентификации
    payments: Тесты платежей
 
    # Специальные
    smoke: Smoke-тесты (быстрая проверка)
    regression: Regression-тесты (проверка старых багов)
 
# === Минимальная версия Python ===
minversion = 3.8
 
# === Паттерны для поиска тестов ===
python_files = test_*.py *_test.py
python_classes = Test*
python_functions = test_*
 
# === Игнорировать директории ===
norecursedirs =
    .git
    .venv
    venv
    node_modules
    build
    dist
    *.egg-info

Для CI/CD

# pytest.ini (для CI)
 
[pytest]
testpaths = tests
 
addopts =
    -v
    --tb=short
    --strict-markers
    --cov=src
    --cov-report=term
    --cov-report=xml  # Для SonarQube/Codecov
    --cov-fail-under=80  # Минимум 80% покрытия
    --maxfail=5  # Остановить после 5 ошибок (экономим время CI)
    --junitxml=junit.xml  # XML отчёт для CI
 
markers =
    slow: Медленные тесты
    integration: Integration-тесты
 
# Игнорировать warnings от зависимостей
filterwarnings =
    ignore::DeprecationWarning:pkg_resources

Дополнительные настройки

Console output verbosity

[pytest]
# Уровень детализации
console_output_style = progress  # classic, progress, count

Опции:

  • classic — стандартный (по умолчанию)
  • progress — прогресс бар
  • count — счётчик (1/100, 2/100, ...)

Log настройки

[pytest]
# Логирование в тестах
log_cli = true
log_cli_level = INFO
log_cli_format = %(asctime)s [%(levelname)s] %(message)s
log_cli_date_format = %Y-%m-%d %H:%M:%S

Теперь print() и logging работают:

import logging
 
def test_something():
    logging.info("Test started")  # Будет выведено!
    print("Debug info")  # Будет выведено!

Warnings фильтры

[pytest]
# Игнорировать конкретные warnings
filterwarnings =
    error  # Превратить все warnings в ошибки
    ignore::DeprecationWarning  # Игнорировать DeprecationWarning
    ignore::PendingDeprecationWarning
    ignore:.*U.*mode is deprecated:DeprecationWarning  # Regex

Timeout для тестов

pip install pytest-timeout
[pytest]
# Таймаут 300 секунд для каждого теста
timeout = 300

Множественные конфигурации

setup.cfg (альтернатива pytest.ini)

# setup.cfg
 
[tool:pytest]
testpaths = tests
addopts = -v --tb=short
markers =
    slow: Медленные тесты

✅ Работает так же как pytest.ini!

pyproject.toml (для Poetry/Hatch)

# pyproject.toml
 
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = ["-v", "--tb=short"]
markers = [
    "slow: Медленные тесты",
]

Приоритет

Pytest ищет конфигурацию в порядке:

  1. pytest.ini
  2. pyproject.toml
  3. setup.cfg
  4. tox.ini

✅ Используйте pytest.ini для максимальной совместимости!

Практический workflow

Локальная разработка

# pytest.ini настроен на -v --tb=short
pytest
 
# Быстрый режим: только быстрые тесты
pytest -m "not slow"
 
# Отладка: остановка на первой ошибке
pytest -x
 
# С отладчиком
pytest --pdb

CI/CD

# .gitlab-ci.yml
 
test:
  script:
    # pytest.ini уже настроен!
    - pytest # Использует настройки из pytest.ini

pytest.ini для CI:

[pytest]
addopts =
    --cov=src
    --cov-fail-under=80  # Блокирует CI если < 80%
    --maxfail=5
    --junitxml=junit.xml

Что вы изучили

  • pytest.ini — единая конфигурация для команды
  • testpaths — где искать тесты
  • addopts — опции по умолчанию
  • markers — регистрация маркеров
  • filterwarnings — управление warnings
  • Множественные форматы — pytest.ini, setup.cfg, pyproject.toml

Следующий урок

Отлично! Теперь pytest настроен для всей команды. Но как переиспользовать фикстуры между разными файлами тестов?

Переходите к уроку 6: conftest.py: переиспользование фикстур

В следующем уроке вы узнаете:

  • conftest.py для глобальных фикстур
  • Автоиспользование фикстур (autouse)
  • Организация фикстур в проекте
  • Scope и порядок выполнения

Устранение неисправностей

Проверьте что:

  1. Файл называется ТОЧНО pytest.ini (не pytest.cfg)
  2. Файл в корне проекта (рядом с tests/)
  3. Секция называется [pytest] (не [tool:pytest])
# ❌ НЕПРАВИЛЬНО
[pytest]
addopts = -v --tb=short  # Одна строка

# ✅ ПРАВИЛЬНО

[pytest]
addopts =
-v
--tb=short

Добавьте --strict-markers в addopts:

[pytest]
addopts =
--strict-markers # Превращает warnings в ошибки

markers =
slow: Описание
# Локально (используется pytest.ini)
pytest

# CI (переопределяем опции)

pytest --tb=no --maxfail=5

Или используйте переменные окружения:

[pytest]
addopts =
-v # В CI добавится --cov-fail-under=80
# CI
export PYTEST_ADDOPTS="--cov-fail-under=80"
pytest