Маркеры

Что такое маркеры?

подробнее

Маркеры в Pytest — это «ярлыки» (теги), которыми можно помечать тесты для фильтрации, пропуска или изменения их поведения. Реализуется с помощью декоратора вида @pytest.mark.name.
Чтобы вывести все маркеры: pytest --markers

Как запустить промаркированные тесты?

подробнее

Для запуска тестов с конкретным/и маркером используется флаг -m. Это имеет смысл только для маркеров которые служат тегами. Например mark.parametrize бессмысленно запускать через -m.
Для условий используется: and, or, not

Примеры:

  • pytest -m smoke - запустит только тесты с @pytest.mark.smoke.
  • pytest -m "smoke and not slow" - запустит помеченные как smoke, не запустятся которые и smoke и slow.
  • pytest -m "smoke or slow - запустить и те, и другие.

Что будет если повесить маркер над классом (class)?

подробнее

Если повесить маркер над классом, он применится ко всем методам внутри.

Как промаркировать весь модуль?

подробнее

Для этого используется специальная глобальная переменная pytestmark.

Пример

# .../test_my_module.py
# Все тесты в этом файле автоматически получат маркер 'web'
pytestmark = pytest.mark.web

# .../test_my_module2.py
# Если нужно несколько маркеров сразу:
pytestmark = [pytest.mark.web, pytest.mark.slow]

Встроенные маркеры

подробнее
  • @pytest.mark.skip(reason="...") - пропускает тест.
  • @pytest.mark.skipif(условие, reason="...") - пропускает, если выполняется условие.
  • @pytest.mark.xfail(reason="...") - помечает тест как «ожидаемо падающий».
    Параметр strict=True пометит тест красным если он пройдёт.
  • @pytest.mark.parametrize("...", [...]) - передача параметров в тест. (подробнее)
  • @pytest.mark.usefixtures("fix1", ...) - применяет фикстуру к классу/тесту без передачи в аргументы.

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

подробнее

При параметризации теста через @pytest.mark.parametrize можно помечать параметры используя pytest.param(value, marks=...). Этот подход позволяет применять маркеры к отдельным значениям в параметризации, не затрагивая остальные кейсы в этом тесте.
В pytest.param также можно передать индивидуальный id для этого параметра: pytest.param(..., id="special_case").

Пример

@pytest.mark.parametrize("user, status", [
    ("admin", 200),
    ("user", 200),
    # Помечаем только этот конкретный набор параметров:
    pytest.param("guest", 403, marks=pytest.mark.xfail(reason="Баг в правах")),
    pytest.param("banned", 403, marks=pytest.mark.skip(reason="Метод еще не написан"))
])
def test_login(user, status):
    assert get_login_status(user) == status

Создание собственных маркеров

подробнее

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

[pytest]
markers =
    smoke: критически важные тесты
    slow: тесты, которые идут долго

Иерархия маркировки

подробнее

Иерархия маркировки (от частного к общему):

  • Параметр: pytest.param(..., marks=...)
  • Функция/Метод: @pytest.mark.name
  • Класс: @pytest.mark.name над class Test...
  • Модуль (файл): pytestmark = pytest.mark.name в начале файла.
  • Директория/Проект: через хуки в conftest.py.