Repository navigation
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 - специальные функции, которые выполняются в разные моменты жизни теста. В отличии от некоторых других фреймворков, в 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, то тесты будут запускаться в два потока и на выполнение уже понадобится в два раза меньше времени.