Есть ли способ контролировать, как 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):
''' do some setup '''
# Do some setup stuff here
def teardown_class(self):
'''' do some teardown'''
# Do some teardown stuff here
def test1(self):
# Do some test1 related stuff
def test2(self):
# Do some test2 related stuff
....
....
....
def test40(self):
# Do some test40 related stuff
if __name__=='__main()__'
pytest.main(args=[os.path.abspath(__file__)])
Проблема заключается в том, что я хотел бы выполнить "testuites" параллельно, то есть хочу, чтобы testuite1, testsuite2, testsuite3 и testsuite4 запускались параллельно, но отдельные тесты внутри testuites должны выполняться серийно.
Когда я использую плагин "xdist" из py.test и запускаю тесты с использованием "py.test -n 4", py.test собирает все тесты и произвольно загружает балансировку тестов среди 4-х работников. Это приводит к тому, что метод "setup_class" должен выполняться каждый раз каждого теста в модуле "testuitex.py" (который побеждает мою цель. Я хочу, чтобы setup_class выполнялся только один раз для каждого класса, и тесты выполнялись последовательно после этого).
По сути, я хочу, чтобы выполнение выглядело следующим образом:
worker1: executes all tests in testsuite1.py serially
worker2: executes all tests in testsuite2.py serially
worker3: executes all tests in testsuite3.py serially
worker4: executes all tests in testsuite4.py serially
в то время как worker1, worker2, worker3 and worker4
выполняются параллельно.
Есть ли способ достичь этого в рамках "pytest-xidst"?
Единственная возможность, о которой я могу думать, это запустить различные процессы для выполнения каждого тестового пакета отдельно в runner.py:
def test_execute_func(testsuite_path):
subprocess.process('py.test %s' % testsuite_path)
if __name__=='__main__':
#Gather all the testsuite names
for each testsuite:
multiprocessing.Process(test_execute_func,(testsuite_path,))
Ответы
Ответ 1
С pytest-xdist в настоящее время нет какого-либо типа "per-file" или "per-test-suite". Фактически, если распределение по каждому файлу (например, тесты в файле будут выполняться не более чем одним работником за раз), уже поможет вам в использовании, я рекомендую вам записать проблему с проблемой отслеживания проблем pytest в https://bitbucket.org/hpk42/pytest/issues?status=new&status=open и ссылка на ваше хорошее объяснение здесь.
веселит, Хольгер
Ответ 2
Вы можете использовать --dist=loadscope
для группировки всех тестов в одном классе тестов. Вот документ от Pytest-XDist на Pypi
По умолчанию опция -n отправляет ожидающие тесты любому работнику, который доступен, без какого-либо гарантированного заказа, но вы можете управлять этим с помощью этих опций:
--dist=loadscope
: тесты будут сгруппированы по --dist=loadscope
для функций тестирования и по классам для методов тестирования, затем каждая группа будет отправлена доступному работнику, гарантируя, что все тесты в группе выполняются в одном и том же процессе. Это может быть полезно, если у вас есть дорогие приборы уровня модуля или класса. В настоящее время группировки не могут быть настроены, так как группировка по классу имеет приоритет над группировкой по модулю. Эта функция была добавлена в версии 1.19.
--dist=loadfile
: тесты будут сгруппированы по имени файла, а затем будут отправлены доступному работнику, гарантируя, что все тесты в группе выполняются на одном и том же работнике. Эта функция была добавлена в версии 1.21.
Ответ 3
Да, есть такие способы, для xdist версии 1.28.0
следующие параметры:
-
--dist=each
: отправляет все тесты всем узлам, поэтому каждый тест выполняется на каждом узле. -
--dist=load
: Распределяет тесты, собранные по всем узлам, поэтому каждый тест запускается только один раз. Все узлы собирают и отправляют набор тестов, и когда все наборы (наборов тестов) получены, это подтверждается, что они являются идентичными наборами. Затем коллекция разделяется на куски, а куски отправляются на узлы для выполнения. -
--dist=loadscope
Распределяет тесты, собранные по всем узлам, поэтому каждый тест запускается только один раз. Все узлы собирают и отправляют список тестов, и когда все коллекции получены, подтверждается, что они являются идентичными коллекциями. Затем коллекция разделяется на рабочие единицы, сгруппированные по областям тестирования, и эти рабочие единицы передаются на узлы. -
--dist=loadfile
Распределяет тесты, собранные по всем узлам, поэтому каждый тест запускается только один раз. Все узлы собирают и отправляют список тестов, и когда все коллекции получены, подтверждается, что они являются идентичными коллекциями. Затем коллекция разделяется на рабочие единицы, сгруппированные по тестовому файлу, и эти рабочие единицы передаются на узлы.
Если вам нужна дополнительная информация, я рекомендую вам перейти непосредственно к фактической реализации планировщиков и проверить, как осуществляется распределение.