0

Как управлять запуском тестов в параллельном режиме с помощью pytest-xdist?

14

У меня следующая структура директорий:

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 ответ(ов)

0

pytest_mproc (документация: ссылка) предоставляет декоратор "group", который позволяет группировать тесты для последовательного выполнения. Кроме того, он обеспечивает более быструю инициализацию при работе с большим числом ядер по сравнению с xdist и предлагает тестовый фикстуру с "глобальной" областью видимости.

0

Если у вас есть тестовые наборы в директории, как в вопросе, вы можете запустить их параллельно с помощью следующей команды:

pytest -n=$(ls **/test*py | wc -l) --dist=loadfile

Если ваши файлы тестовых наборов находятся в одной директории, то просто используйте:

pytest -n=$(ls test*py | wc -l) --dist=loadfile

В случае, если появится новый файл с тестами, данная команда автоматически включит новый тестовый файл и добавит для него дополнительный рабочий процесс.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь