Какие существуют способы группировки тестов в pytest?

Ответ

В pytest тесты можно группировать как для логической организации кода, так и для выборочного запуска. Основные подходы:

1. Маркеры (Markers)

Это самый гибкий способ для функциональной группировки и выборочного запуска тестов. Тесты помечаются специальными декораторами @pytest.mark.<marker_name>.

Пример:

import pytest

@pytest.mark.smoke
def test_critical_feature():
    assert True

@pytest.mark.regression
@pytest.mark.slow
def test_complex_calculation():
    # ... долгие вычисления
    assert 1 + 1 == 2

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

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

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

# Запустить тесты, которые являются и regression, и slow
pytest -m "regression and slow"

Best practice: Регистрируйте свои маркеры в файле pytest.ini или pyproject.toml, чтобы избежать предупреждений.

# pytest.ini
[pytest]
markers = 
    smoke: critical path tests
    regression: regression tests
    slow: slow running tests

2. Классы

Классы используются для логического объединения тестов, связанных с одним объектом или функциональностью. Названия классов должны начинаться с Test.

class TestUserAuth:
    def test_login(self):
        assert True

    def test_logout(self):
        assert True

    def test_invalid_password(self):
        assert False

3. Файлы и директории

pytest автоматически обнаруживает тесты в файлах test_*.py или *_test.py. Разделение тестов по разным файлам и директориям является естественным способом их группировки по модулям или компонентам приложения.

/tests
├── test_api
│   ├── test_auth.py
│   └── test_payments.py
└── test_db
    └── test_models.py

Запустить все тесты, связанные с API:

pytest tests/test_api/

Ответ 18+ 🔞

Смотри, чтобы не размазывать свои тесты по всему проекту как говно по стенке, в pytest есть несколько способов их сгруппировать. И для порядка, и чтобы запускать выборочно, а не всё подряд, как дурак.

1. Маркеры (Markers) — твои лучшие друзья

Это, блядь, самый гибкий способ. Вешаешь на тест декоратор @pytest.mark.<твоя_метка> и потом как царь выбираешь, что запускать.

Вот смотри, как просто:

import pytest

@pytest.mark.smoke  # Критичный путь, без этого на прод не пускают
def test_critical_feature():
    assert True

@pytest.mark.regression  # Регрессия, ебать её в сраку
@pytest.mark.slow        # Медленный, как черепаха в сиропе
def test_complex_calculation():
    # ... тут какие-то долгие вычисления
    assert 1 + 1 == 2

А запускаешь вот так, с прицелом:

# Только дымовые, быстро проверить
pytest -m smoke

# Всё, кроме этих долбоёбов, которые вечно тормозят
pytest -m "not slow"

# А вот это уже комбо: и регрессия, и медленный. Настоящий мазохистский набор.
pytest -m "regression and slow"

Важный лайфхак, ёпта: Зарегистрируй свои маркеры в pytest.ini, чтобы питон не орал предупреждениями, как сумасшедший.

# pytest.ini
[pytest]
markers = 
    smoke: критичные тесты основного пути
    regression: тесты на регрессию
    slow: медленные, как ебучий яндекс-браузер

2. Классы — для порядка в голове

Если тесты про одно и то же, логично их в класс запихнуть. Название класса должно начинаться с Test, иначе питон его проигнорит, как пустое место.

class TestUserAuth:
    def test_login(self):
        assert True

    def test_logout(self):
        assert True

    def test_invalid_password(self):
        assert False  # Ну тут понятно, пиздец случится

3. Файлы и папки — как в жизни

pytest сам, такой умный, находит тесты в файлах test_*.py или *_test.py. Так что просто раскидай их по папкам, как мусор по разным ведёркам.

/tests
├── test_api
│   ├── test_auth.py
│   └── test_payments.py
└── test_db
    └── test_models.py

Хочешь гонять только апишные тесты? Да не вопрос!

pytest tests/test_api/

Вот и вся магия. Ничего сложного, главное — не устраивать из своего кода свалку, где всё в одну кучу.