Как управлять запуском тестов в параллельном режиме с помощью pytest-xdist?
У меня следующая структура директорий:
runner.py
lib/
tests/
testsuite1/
testsuite1.py
testsuite2/
testsuite2.py
testsuite3/
testsuite3.py
testsuite4/
testsuite4.py
Формат модулей testsuite*.py
выглядит следующим образом:
import pytest
class testsomething:
def setup_class(self):
''' выполняем предварительную настройку '''
# Здесь выполняем некоторые подготовительные действия
def teardown_class(self):
''' выполняем завершающие действия '''
# Здесь выполняем завершающие действия
def test1(self):
# Здесь выполняем действия, связанные с тестом 1
def test2(self):
# Здесь выполняем действия, связанные с тестом 2
....
....
....
def test40(self):
# Здесь выполняем действия, связанные с тестом 40
if __name__=='__main__':
pytest.main(args=[os.path.abspath(__file__)])
Проблема заключается в том, что я хотел бы выполнять тестовые наборы параллельно, т.е. я хочу, чтобы testsuite1
, testsuite2
, testsuite3
и testsuite4
начали выполнение параллельно, но отдельные тесты внутри тестовых наборов должны выполняться последовательно.
Когда я использую плагин xdist
от pytest и запускаю тесты с помощью py.test -n 4
, pytest собирает все тесты и случайным образом распределяет их между 4 рабочими процессами. Это приводит к тому, что метод setup_class
выполняется каждый раз для каждого теста в модуле testsuitex.py
, что противоречит моей цели. Я хочу, чтобы setup_class
выполнялся только один раз для класса, а тесты выполнялись последовательно после этого.
По сути, я хочу, чтобы выполнение выглядело так:
worker1: выполняет все тесты в testsuite1.py последовательно
worker2: выполняет все тесты в testsuite2.py последовательно
worker3: выполняет все тесты в testsuite3.py последовательно
worker4: выполняет все тесты в testsuite4.py последовательно
при этом worker1
, worker2
, worker3
и worker4
выполнялись бы в параллели.
Есть ли способ достичь этого в рамках pytest-xdist
?
Единственный вариант, который я могу придумать, это запустить разные процессы для выполнения каждого тестового набора отдельно в runner.py
:
def test_execute_func(testsuite_path):
subprocess.process('py.test %s' % testsuite_path)
if __name__=='__main__':
# Собрать все названия тестовых наборов
for each testsuite:
multiprocessing.Process(test_execute_func,(testsuite_path,))
2 ответ(ов)
pytest_mproc
(документация: ссылка) предоставляет декоратор "group", который позволяет группировать тесты для последовательного выполнения. Кроме того, он обеспечивает более быструю инициализацию при работе с большим числом ядер по сравнению с xdist
и предлагает тестовый фикстуру с "глобальной" областью видимости.
Если у вас есть тестовые наборы в директории, как в вопросе, вы можете запустить их параллельно с помощью следующей команды:
pytest -n=$(ls **/test*py | wc -l) --dist=loadfile
Если ваши файлы тестовых наборов находятся в одной директории, то просто используйте:
pytest -n=$(ls test*py | wc -l) --dist=loadfile
В случае, если появится новый файл с тестами, данная команда автоматически включит новый тестовый файл и добавит для него дополнительный рабочий процесс.
Как вывести стандартный вывод print() в консоль во время выполнения pytest?
Что такое conftest.py в Pytest?
Разделение файла conftest.py на несколько более мелких частей, похожих на conftest
Работают ли параметризованные тесты pytest с тестами на основе классов unittest?
Как заставить фикстуры pytest работать с декорированными функциями?