Skip to content
Nikolaev Dmitriy edited this page May 13, 2023 · 7 revisions

Установка Pytest

pip install pytest

Аргументы запуска

pytest test.py::test_func                  # запустить конкретный тест в модуле используя уникальный идентификатор узла
pytest test.py::TestClass::test_method     # запустить конкретный тест в модуле используя уникальный идентификатор класса
pytest -s                                  # выводит в консоль все print()-сообщения
pytest -v                                  # выводит расширенную информацию о тесте //verbose
pytest -l                                  # выводит значения переменных в момент ошибки
pytest -k "http or quick"                  # запустить группу тестов на основе совпадения подстроки в имени функции/метода теста //-k <expr>
pytest -m dev                              # запустит все тесты с маркой dev
pytest --co                                # позволяет вывести все доступные тесты в директории
pytest --markers                           # вывод всех доступных марок в проекте
pytest --fixtures                          # выводит список всех доступных фикстур
pytest -durations=x                        # вывод x самых долгих тестов
pytest --setup-plan                        # тесты не запускает, но выводит план запуска тестов
pytest --version                           # показывает, откуда был импортирован pytest
pytest -h | --help                         # показать справку по параметрам командной строки и конфигурационного файла

Марки

Марки позволяют маркировать тесты, разделять их на группы, управлять отдельными тестами и группами.

  • Марка skip позволяет пропустить тест и не выполнять его содержимое. С помощью аргумента reason следует указывать причину пропуска

    @pytest.mark.skip()
    @pytest.mark.skip(reason="Этот тест еще не завершен")
  • Марка xfail позволяет указать, что тест заведомо может не работать. При этом тест запустится. Причину также указывают с помощью аргумента reason, а аргумент strict заставляет тест упасть, если ошибка не произошла сама. Аргумент raises заставляет тест отработать только в том случае, если в тесте есть какой-то конкретный тип ошибки

    @pytest.mark.xfail()
    @pytest.mark.xfail(reason="", strict=True, raises="AssertionError")
  • Марка Skip If позволяет пропустить тест при выполнения условия. Условие указывается первым аргументом. Также можно указать причину, по которой мы пропускаем тест. К примеру, reason="Condition".

    @pytest.mark.skipif()
    def some_test():
        pass

Pytest Hooks (Хуки)

Хуки в Pytest - специальные функции, которые выполняются в разные моменты жизни теста. В отличии от некоторых других фреймворков, в Pytest есть возможность влиять на тест во время его выполнения. Также важно учитывать, что хуки применимы в основном в больших проектах. В простых тестах они бывают лишними.

Основные хуки в Pytest:

  • pytest_addoption - добавляет новые функции;
  • pytest_configure - изменяет конфигурацию;
  • pytest_sessionstart - действия перед стартом всех тестов;
  • pytest_generate_tests - изменяем параметризацию тестов;
  • pytest_collection_modifyitems - редактирование собранных тестов;
  • pytest_runtestloop - хуки во время выполнения тестов;
  • pytest_sessionfinish - все тесты завершились.

Все хуки в Pytest прописываются в файле conftest.py.

Дерево последовательности выполнения тестов и вызова хуков (ссылка):

root
└── pytest_cmdline_main
    ├── pytest_plugin_registered
    ├── pytest_configure
    │   └── pytest_plugin_registered
    ├── pytest_sessionstart
    │   ├── pytest_plugin_registered
    │   └── pytest_report_header
    ├── pytest_collection
    │   ├── pytest_collectstart
    │   ├── pytest_make_collect_report
    │   │   ├── pytest_collect_file
    │   │   │   └── pytest_pycollect_makemodule
    │   │   └── pytest_pycollect_makeitem
    │   │       └── pytest_generate_tests
    │   │           └── pytest_make_parametrize_id
    │   ├── pytest_collectreport
    │   ├── pytest_itemcollected
    │   ├── pytest_collection_modifyitems
    │   └── pytest_collection_finish
    │       └── pytest_report_collectionfinish
    ├── pytest_runtestloop
    │   └── pytest_runtest_protocol
    │       ├── pytest_runtest_logstart
    │       ├── pytest_runtest_setup
    │       │   └── pytest_fixture_setup
    │       ├── pytest_runtest_makereport
    │       ├── pytest_runtest_logreport
    │       │   └── pytest_report_teststatus
    │       ├── pytest_runtest_call
    │       │   └── pytest_pyfunc_call
    │       ├── pytest_runtest_teardown
    │       │   └── pytest_fixture_post_finalizer
    │       └── pytest_runtest_logfinish
    ├── pytest_sessionfinish
    │   └── pytest_terminal_summary
    └── pytest_unconfigure

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

Для успешного параллельных тестов важно помнить:

  • тесты не должны зависеть друг от друга;
  • тесты не должны менять окружение так, чтобы это влияло на прохождение других тестов.

Для параллельного запуска тестов используется плагин xdist, который разрабатывается командой Pytest. У xdist есть аргументы запуска. Основным таким аргументом является -n numprocesses, который принимает количество параллелей для запуска. Также можно передать auto для автоматической настройки. Остальные аргументы ситуативные и редко используются, получить информация о них можно с помощью команды help.

Пример: К примеру, у нас есть тест, который выполняется 20 раз и каждое выполнение занимает одну секунду:

@pytest.mark.parametrize("param", range(20))
def test_many_params(param, session_scoped_fixture):
    time.sleep(1)

Если запустить тест обычным способом с помощью команды pytest -v -k test_many_params, то тесты начнут выполнятся поочерёдно и это займет приблизительно 20 секунд. Если этот же тест запустить с помощью команды pytest -v -k test_many_params -n 2, то тесты будут запускаться в два потока и на выполнение уже понадобится в два раза меньше времени.

Clone this wiki locally