Что такое pytest?

pytest — это мощный и популярный фреймворк тестирования для Python, который делает написание тестов простым и масштабируемым. Он поддерживает как простые unit-тесты, так и сложные функциональные тесты.

Установка и настройка

1# Установка через pip
2pip install pytest
3
4# Установка через poetry
5poetry add pytest --group dev

Простой пример теста

 1# test_calculator.py
 2def add(a, b):
 3    return a + b
 4
 5def test_add():
 6    assert add(2, 3) == 5
 7    assert add(-1, 1) == 0
 8    assert add(0, 0) == 0
 9
10def test_add_strings():
11    assert add("hello", " world") == "hello world"

Запуск тестов:

 1# Запуск всех тестов
 2pytest
 3
 4# Запуск конкретного файла
 5pytest test_calculator.py
 6
 7# Запуск с подробным выводом
 8pytest -v
 9
10# Запуск с покрытием кода
11pytest --cov=src

Фикстуры (Fixtures)

Фикстуры позволяют настроить тестовое окружение:

 1import pytest
 2from myapp.database import Database
 3
 4@pytest.fixture
 5def database():
 6    db = Database()
 7    db.connect()
 8    yield db  # предоставляем базу тестам
 9    db.disconnect()  # очистка после тестов
10
11@pytest.fixture(scope="session")
12def api_client():
13    """Фикстура на уровне сессии"""
14    return APIClient()
15
16def test_user_creation(database):
17    user = database.create_user("test@example.com")
18    assert user.email == "test@example.com"

Параметризованные тесты

 1import pytest
 2
 3@pytest.mark.parametrize("input,expected", [
 4    (2, 4),
 5    (3, 9),
 6    (4, 16),
 7    (0, 0),
 8])
 9def test_square(input, expected):
10    assert input ** 2 == expected
11
12@pytest.mark.parametrize("username,password,expected", [
13    ("admin", "password123", True),
14    ("user", "wrong", False),
15    ("", "password", False),
16])
17def test_login(username, password, expected):
18    result = authenticate(username, password)
19    assert result == expected

Конфигурация через conftest.py

 1# conftest.py
 2import pytest
 3from myapp import create_app
 4
 5@pytest.fixture(scope="session")
 6def app():
 7    """Создание тестового приложения"""
 8    app = create_app(testing=True)
 9    return app
10
11@pytest.fixture
12def client(app):
13    """Тестовый клиент"""
14    return app.test_client()
15
16def pytest_configure(config):
17    """Глобальная конфигурация pytest"""
18    config.addinivalue_line(
19        "markers", "slow: marks tests as slow"
20    )

Маркеры (Markers)

 1import pytest
 2
 3@pytest.mark.slow
 4def test_heavy_computation():
 5    # Медленный тест
 6    pass
 7
 8@pytest.mark.integration
 9def test_database_integration():
10    # Интеграционный тест
11    pass
12
13@pytest.mark.skip(reason="Не реализовано")
14def test_future_feature():
15    pass
16
17@pytest.mark.skipif(sys.version_info < (3, 8), 
18                   reason="Требует Python 3.8+")
19def test_new_feature():
20    pass

Запуск тестов по маркерам:

1# Запуск только медленных тестов
2pytest -m slow
3
4# Исключение медленных тестов
5pytest -m "not slow"
6
7# Комбинирование маркеров
8pytest -m "integration and not slow"

Популярные плагины

  • pytest-cov — измерение покрытия кода
  • pytest-xdist — параллельное выполнение тестов
  • pytest-mock — улучшенная работа с mock
  • pytest-django — тестирование Django приложений
  • pytest-asyncio — тестирование асинхронного кода

Преимущества pytest

  • Простой и интуитивный синтаксис
  • Мощная система фикстур
  • Автоматическое обнаружение тестов
  • Богатая экосистема плагинов
  • Подробные отчёты об ошибках
  • Поддержка параллельного выполнения

Рекомендации по использованию

  • Структурируй тесты в логические группы
  • Используй осмысленные имена для тестов и фикстур
  • Настрой pytest.ini для конфигурации проекта
  • Применяй маркеры для категоризации тестов
  • Измеряй покрытие кода и стремись к высоким показателям

FAQ

Как тестировать асинхронный код?

Используй плагин pytest-asyncio и декоратор @pytest.mark.asyncio для тестирования async/await функций.

Можно ли использовать pytest с Django?

Да, плагин pytest-django обеспечивает отличную интеграцию с Django, включая тестовую базу данных и фикстуры.