Что такое pytest?
pytest — это мощный и популярный фреймворк тестирования для Python, который делает написание тестов простым и масштабируемым. Он поддерживает как простые unit-тесты, так и сложные функциональные тесты.
Установка и настройка
Простой пример теста
Запуск тестов:
Фикстуры (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
Запуск тестов по маркерам:
Популярные плагины
- 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, включая тестовую базу данных и фикстуры.