Deprecated: Creation of dynamic property Yoast\Presenters\CommonArticlePresenter::$metaPropertyType is deprecated in /var/www/html/web/app/themes/tutortop-blog/Yoast/Presenters/CommonArticlePresenter.php on line 26

Deprecated: Creation of dynamic property Yoast\Presenters\CommonArticlePresenter::$metaPropertyType is deprecated in /var/www/html/web/app/themes/tutortop-blog/Yoast/Presenters/CommonArticlePresenter.php on line 26

Deprecated: Creation of dynamic property Yoast\Presenters\CommonArticlePresenter::$metaPropertyType is deprecated in /var/www/html/web/app/themes/tutortop-blog/Yoast/Presenters/CommonArticlePresenter.php on line 26
Как запустить pytest: подробное руководство по тестированию Python-кода
26.06.2025
142
15.5 мин

Как запустить pytest: полное руководство по тестированию Python-приложений

Установка и первоначальная настройка pytest

Перед тем как запустить pytest, необходимо убедиться в правильной установке. Pytest не входит в стандартную библиотеку Python, поэтому требует отдельной установки. Наиболее надежный способ установки — использование pip в виртуальном окружении:

python -m venv test_env
source test_env/bin/activate # для Linux/macOS
test_env\Scripts\activate # для Windows
pip install pytest

Проверить успешность установки можно командой:

pytest --version

Альтернативный способ запуска, который гарантирует использование правильной версии Python и избегает проблем с PATH:

python -m pytest --version

Как отмечает Brian Okken, автор книги «Python Testing with pytest»: «Использование python -m pytest вместо просто pytest — это лучшая практика, которая избавляет от многих проблем с окружением в корпоративных проектах.»

Для тех, кто хочет развиваться в профессии тестировщика и освоить автоматизацию, могут быть полезны онлайн-курсы по тестированию.

Основные способы запуска pytest

Pytest предоставляет несколько способов запуска тестов, каждый из которых подходит для определенных сценариев использования.

Базовый запуск всех тестов

Самый простой способ запустить все тесты в проекте:

pytest

Или более надежный вариант:

python -m pytest

При запуске без параметров pytest автоматически обнаруживает все файлы, соответствующие паттерну test_*.py или *_test.py, и выполняет все функции, начинающиеся с test_ или заканчивающиеся на _test.

Запуск конкретного файла с тестами

Для запуска тестов из определенного файла:

pytest test_example.py

Можно указать несколько файлов одновременно:

pytest test_example.py test_utils.py test_models.py

Запуск конкретного теста или группы тестов

Для выполнения отдельной тестовой функции:

pytest test_example.py::test_function_name

Для запуска всех тестов в классе:

pytest test_example.py::TestClass

Для запуска конкретного метода в классе:

pytest test_example.py::TestClass::test_method

Запуск тестов в директории

Чтобы запустить все тесты в определенной папке:

pytest tests/

Pytest рекурсивно обойдет все поддиректории и найдет соответствующие тестовые файлы.

Управление выводом и детализацией

Одним из ключевых преимуществ pytest является гибкая система управления выводом информации о тестах.

Уровни детализации вывода

Pytest поддерживает несколько уровней детализации:

# Минимальный вывод
pytest -q

# Подробный вывод
pytest -v

# Очень подробный вывод
pytest -vv

В режиме -v pytest показывает название каждого выполняемого теста, что особенно полезно при отладке медленных тестов или при необходимости отслеживать прогресс выполнения большого набора тестов.

Отображение локальных переменных при ошибках

Для получения дополнительной информации об ошибках:

pytest -l  # показать локальные переменные в трассировке
pytest --tb=short # краткая трассировка
pytest --tb=long # подробная трассировка
pytest --tb=no # без трассировки

Захват вывода

По умолчанию pytest захватывает весь вывод stdout и stderr. Для отключения этого поведения:

pytest -s  # отключить захват вывода

Это особенно полезно при отладке, когда нужно видеть print-сообщения в реальном времени.

Планшет в руках человека

Фильтрация и выбор тестов

В крупных проектах важно уметь запускать только определенные подмножества тестов.

Фильтрация по ключевым словам

Опция -k позволяет фильтровать тесты по имени:

# Запустить только тесты, содержащие "user" в названии
pytest -k user

# Запустить тесты, содержащие "user", но не "admin"
pytest -k "user and not admin"

# Запустить тесты, содержащие "fast" или "quick"
pytest -k "fast or quick"

Использование меток (markers)

Pytest поддерживает систему меток для группировки тестов:

# В тестовом файле
import pytest

@pytest.mark.slow
def test_heavy_computation():
# Медленный тест
pass

@pytest.mark.fast
def test_simple_operation():
# Быстрый тест
pass

Запуск тестов с определенными метками:

# Запустить только быстрые тесты
pytest -m fast

# Запустить все тесты кроме медленных
pytest -m "not slow"

# Запустить тесты с несколькими метками
pytest -m "fast or integration"

Практический пример использования меток

В реальном проекте электронной коммерции команда разработки использует следующую систему меток:

# conftest.py
import pytest

def pytest_configure(config):
config.addinivalue_line("markers", "unit: unit tests")
config.addinivalue_line("markers", "integration: integration tests")
config.addinivalue_line("markers", "e2e: end-to-end tests")
config.addinivalue_line("markers", "slow: slow running tests")
config.addinivalue_line("markers", "database: tests requiring database")

# Запуск разных наборов тестов:
# pytest -m unit # только модульные тесты
# pytest -m "not slow" # исключить медленные тесты
# pytest -m "integration and database" # интеграционные тесты с БД

Управление выполнением тестов

Остановка при первой ошибке

Для быстрой отладки можно остановить выполнение при первом падении:

pytest -x  # остановиться после первой ошибки
pytest --maxfail=3 # остановиться после 3 ошибок

Повторный запуск упавших тестов

Pytest запоминает результаты предыдущих запусков:

pytest --lf  # запустить только упавшие в прошлый раз тесты
pytest --ff # запустить сначала упавшие, потом остальные

Эта функциональность значительно ускоряет цикл разработки при исправлении ошибок.

Параллельное выполнение тестов

С помощью плагина pytest-xdist можно запускать тесты параллельно:

pip install pytest-xdist
pytest -n auto # автоматически определить количество процессов
pytest -n 4 # использовать 4 процесса

По данным исследования команды pytest, параллельное выполнение может ускорить тесты в 2-4 раза на многоядерных системах, особенно при наличии медленных I/O операций.

Продвинутые опции запуска

Профилирование времени выполнения

Для оптимизации производительности тестов:

pytest --durations=10  # показать 10 самых медленных тестов
pytest --durations=0 # показать время всех тестов

Отладка с помощью PDB

Pytest интегрируется с отладчиком Python:

pytest --pdb         # запустить отладчик при ошибке
pytest --pdbcls=IPython.terminal.debugger:Pdb # использовать IPython отладчик

Сбор информации о покрытии кода

С плагином pytest-cov:

pip install pytest-cov
pytest --cov=myproject # показать покрытие для пакета myproject
pytest --cov=myproject --cov-report=html # создать HTML-отчет

Генерация отчетов в различных форматах

Pytest поддерживает множество форматов отчетов:

# JUnit XML для CI/CD систем
pytest --junit-xml=report.xml

# JSON отчет
pip install pytest-json-report
pytest --json-report --json-report-file=report.json

# HTML отчет
pip install pytest-html
pytest --html=report.html --self-contained-html

Конфигурирование pytest через файлы настроек

Для избежания повторения длинных команд pytest поддерживает различные способы конфигурирования.

Использование pytest.ini

# pytest.ini
[tool:pytest]
minversion = 6.0
addopts = -ra -q --strict-markers --strict-config
testpaths = tests
python_files = tests/*.py
python_classes = Test*
python_functions = test_*
markers =
slow: marks tests as slow (deselect with '-m "not slow"')
serial
integration: marks tests as integration tests

Использование pyproject.toml

# pyproject.toml
[tool.pytest.ini_options]
minversion = "6.0"
addopts = [
    "-ra",
    "--strict-markers",
    "--strict-config",
    "--cov=src",
    "--cov-report=term-missing:skip-covered",
    "--cov-report=html:htmlcov",
    "--cov-report=xml",
]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]

Переменные окружения

Pytest учитывает переменные окружения:

# Установка переменных для pytest
export PYTEST_ADDOPTS="-v --tb=short"
export PYTEST_PLUGINS="pytest_html,pytest_cov"

Интеграция с различными инструментами

Запуск из IDE

Большинство современных IDE поддерживают pytest:

  • PyCharm: встроенная поддержка с графическим интерфейсом для запуска и отладки тестов
  • VS Code: расширение Python Test Explorer обеспечивает удобный интерфейс
  • Sublime Text: пакет SublimePytest добавляет команды для запуска тестов

Интеграция с CI/CD

Пример конфигурации для GitHub Actions:

# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.9, '3.10', 3.11]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest pytest-cov
pip install -r requirements.txt
- name: Test with pytest
run: |
pytest --cov=./ --cov-report=xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3

Использование в Docker

# Dockerfile для тестирования
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["pytest", "--cov=src", "--cov-report=term-missing"]

Сравнительный анализ способов запуска pytest

Способ запускаПреимуществаНедостаткиРекомендуемое использование
pytestКраткий, быстрый наборЗависит от PATHЛокальная разработка в простых проектах
python -m pytestГарантированно использует текущий PythonНемного длиннееПродакшн, CI/CD, виртуальные окружения
IDE интеграцияУдобный GUI, отладкаПривязка к конкретной IDEАктивная разработка и отладка
Makefile/скриптыСтандартизация команд в командеДополнительная сложностьКорпоративные проекты
Docker контейнерыИзолированная средаМедленный стартCI/CD, воспроизводимые тесты

Практические сценарии использования

Сценарий 1: Разработка нового функционала

При разработке нового модуля в проекте интернет-магазина разработчик использует следующий подход:

# Быстрая проверка новых тестов
pytest tests/test_cart.py::test_add_item -v

# Проверка всего модуля после изменений
pytest tests/test_cart.py --tb=short

# Финальная проверка с покрытием
pytest tests/test_cart.py --cov=src.cart --cov-report=term-missing

Сценарий 2: Рефакторинг существующего кода

При рефакторинге критически важного модуля:

# Сначала запустить все связанные тесты
pytest -k "payment or transaction" -v

# При ошибках - остановиться на первой для быстрого исправления
pytest -k "payment or transaction" -x --pdb

# Проверить регрессию во всей системе
pytest --lf --maxfail=5

Сценарий 3: Подготовка к релизу

Перед выпуском новой версии:

# Полный прогон всех тестов с детальной статистикой
pytest --cov=src --cov-report=html --durations=20 --tb=short

# Проверка только критически важных тестов
pytest -m "not slow" --maxfail=1

# Генерация отчетов для stakeholders
pytest --html=reports/test_report.html --self-contained-html

Оптимизация производительности тестов

Согласно исследованию Microsoft Research, медленные тесты являются одной из главных причин снижения продуктивности разработчиков. Команды, у которых полный прогон тестов занимает более 10 минут, на 23% чаще пропускают запуск тестов перед коммитом.

Стратегии ускорения тестов

Профилирование и оптимизация:

# Найти самые медленные тесты
pytest --durations=0 | head -20

# Запуск в параллель с учетом зависимостей
pytest -n auto --dist=loadscope

# Использование кеширования
pytest --cache-clear # очистить кеш при необходимости

Группировка тестов по скорости выполнения

# pytest.ini
[tool:pytest]
markers =
    unit: fast unit tests (< 0.1s each)
    integration: integration tests (< 1s each)  
    slow: slow tests (> 1s each)
    
# Запуск быстрых тестов во время разработки
pytest -m "unit or integration"

# Полный прогон в CI
pytest -m "unit or integration or slow"

Обработка ошибок и отладка

Типичные проблемы при запуске pytest

Проблема: ImportError при запуске тестов

# Решение: правильная настройка PYTHONPATH
export PYTHONPATH="${PYTHONPATH}:${PWD}/src"
pytest

# Или использование установки в режиме разработки
pip install -e .

Проблема: Тесты не обнаруживаются

# Проверка обнаружения тестов без запуска
pytest --collect-only

# Настройка в pytest.ini для нестандартных паттернов
[tool:pytest]
python_files = test_*.py *_test.py check_*.py
python_functions = test_* check_*

Продвинутая отладка

Для сложных случаев отладки pytest предоставляет дополнительные инструменты:

# Подробная информация о сборе тестов
pytest --collect-only -q

# Отображение причин пропуска тестов
pytest -rs

# Информация о фикстурах
pytest --fixtures test_file.py

# Отладка с сохранением состояния
pytest --pdbcls=IPython.terminal.debugger:Pdb --capture=no
Человек работает за ноутбуком

Интеграция с системами мониторинга

В enterprise-окружениях важно интегрировать pytest с системами мониторинга и аналитики:

Отправка метрик в системы мониторинга

# conftest.py - отправка метрик в Prometheus
import pytest
import time
from prometheus_client import Counter, Histogram

TEST_COUNTER = Counter('pytest_tests_total', 'Total tests run', ['status'])
TEST_DURATION = Histogram('pytest_test_duration_seconds', 'Test duration')

@pytest.hookimpl(tryfirst=True)
def pytest_runtest_makereport(item, call):
if call.when == 'call':
if call.excinfo is None:
TEST_COUNTER.labels(status='passed').inc()
else:
TEST_COUNTER.labels(status='failed').inc()

TEST_DURATION.observe(call.duration)

Интеграция с системами уведомлений

# Отправка уведомлений в Slack при критических ошибках
pytest --tb=short --maxfail=1 || curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Critical tests failed in production!"}' \
$SLACK_WEBHOOK_URL

Часто задаваемые вопросы

Как запустить pytest в среде с несколькими версиями Python?

Для тестирования на нескольких версиях Python используйте tox:

# tox.ini
[tox]
envlist = py38,py39,py310,py311

[testenv]
deps = pytest
commands = pytest {posargs}

Запуск: tox для всех версий или tox -e py311 для конкретной версии.

Можно ли запускать pytest из Python-кода программно?

Да, pytest предоставляет программный API:

import pytest
import sys

# Запуск с получением результата
exit_code = pytest.main(['-v', 'tests/'])
if exit_code != 0:
sys.exit(exit_code)

# Более сложный пример с настройками
pytest.main([
'--tb=short',
'--cov=src',
'--cov-report=term-missing',
'tests/'
])

Как правильно организовать структуру проекта для pytest?

Рекомендуемая структура проекта:

myproject/
├── src/
│ └── myproject/
│ ├── __init__.py
│ └── module.py
├── tests/
│ ├── __init__.py
│ ├── conftest.py
│ ├── unit/
│ │ └── test_module.py
│ └── integration/
│ └── test_integration.py
├── pytest.ini
└── setup.py

Такая структура обеспечивает четкое разделение кода и тестов, упрощает навигацию и позволяет легко настраивать различные типы тестов.

Заключение и практические рекомендации

Эффективное использование pytest начинается с понимания того, что это не просто инструмент для запуска тестов, а целая экосистема для управления качеством кода. Правильная настройка и использование pytest может значительно повысить продуктивность команды разработки и качество продукта.

Практический чек-лист для внедрения pytest

  • Базовая настройка: Создайте pytest.ini или настройте pyproject.toml с базовыми опциями для вашего проекта
  • Структура проекта: Организуйте четкую структуру директорий с разделением на unit, integration и e2e тесты
  • Система меток: Внедрите консистентную систему маркировки тестов для удобной фильтрации
  • CI/CD интеграция: Настройте автоматический запуск тестов с генерацией отчетов и метрик покрытия
  • Мониторинг производительности: Регулярно анализируйте время выполнения тестов и оптимизируйте медленные тесты

Ключевые выводы

  • Использование python -m pytest вместо pytest решает большинство проблем с окружением
  • Правильная конфигурация через файлы настроек экономит время и стандартизирует процессы в команде
  • Система меток и фильтрации позволяет эффективно управлять большими наборами тестов
  • Параллельное выполнение и кеширование результатов могут значительно ускорить feedback loop
  • Интеграция с системами мониторинга и CI/CD превращает тестирование в автоматизированный процесс контроля качества

Оцените статью

4.6 5 (14 оценок)
Хочу стать тестировщиком!
Специально для вас мы собрали отдельную подборку лучших онлайн-курсов по QA-тестированию на рынке и сравнили их по цене, продолжительности и отзывам студентов.
Подборка курсов Python