Подтвердить что ты не робот

Есть ли способ контролировать, как 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,))
4b9b3361

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

Если вам нужна дополнительная информация, я рекомендую вам перейти непосредственно к фактической реализации планировщиков и проверить, как осуществляется распределение.