是否可以控制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__)])
我遇到的问题是,我想要并行执行这些'testsuites',也就是说,我希望testsuite1、testsuite2、testsuite3和testsuite4能够同时开始执行,但每个testsuite内部的测试需要依次执行。
当我使用py.test的'xdist'插件,并通过'py.test -n 4'来启动测试时,py.test会收集所有的测试,并随机将这些测试分配给4个工作进程。这导致'testsuitex.py'模块中的每个测试都要每次都执行'setup_class'方法(这正好与我的目的相悖。我希望'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 和 worker4
。
有没有办法在'pytest-xdist'框架中实现这个目标?
我能想到的唯一选项是启动不同的进程,在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,))
6 个回答
目前,使用pytest-xdist时,并没有“按文件”或“按测试套件”来分配测试的功能。实际上,如果你希望每个文件的测试(比如一个文件里的测试最多只能被一个工作者同时执行)能帮助到你的情况,我建议你去pytest的问题追踪器提交一个功能请求,可以在这里找到:https://bitbucket.org/hpk42/pytest/issues?status=new&status=open,并把你在这里的详细解释链接过去。
祝好,holger
可用的多种选项
是的,有这样的方式,针对版本 1.28.0
的 xdist,提供了以下几种选项:
--dist=each
: 将所有测试发送到所有节点,这样每个测试都会在每个节点上运行一次。--dist=load
: 在所有节点之间分配收集到的测试,这样每个测试只会运行一次。所有节点会收集并提交测试套件,当所有的测试套件都收集完后,会检查它们是否完全相同。然后,这些测试会被分成小块,分配给节点去执行。--dist=loadscope
: 在所有节点之间分配收集到的测试,这样每个测试只会运行一次。所有节点会收集并提交测试列表,当所有的列表都收集完后,会检查它们是否完全相同。然后,这些测试会根据测试范围分成工作单元,再将这些工作单元分配给节点。--dist=loadfile
: 在所有节点之间分配收集到的测试,这样每个测试只会运行一次。所有节点会收集并提交测试列表,当所有的列表都收集完后,会检查它们是否完全相同。然后,这些测试会根据测试文件分成工作单元,再将这些工作单元分配给节点。
如果你需要更多信息,建议直接查看 调度器的实际实现,了解分配是如何进行的。
你可以使用 --dist=loadscope
来把同一个测试类里的所有测试放在一起。这里有来自 pytest-xdist 在 pypi 的文档
默认情况下,-n 选项会把待执行的测试分配给任何可用的工作者,顺序是没有保证的,但你可以用以下选项来控制:
--dist=loadscope
:测试会按模块分组(对于测试函数)和按类分组(对于测试方法),然后每个组会被发送到一个可用的工作者,这样可以确保同一组里的所有测试都在同一个进程中运行。如果你的模块级或类级的准备工作比较复杂,这个功能会很有用。目前,分组方式不能自定义,按类分组的优先级高于按模块分组。这项功能是在 1.19 版本中添加的。
--dist=loadfile
:测试会按文件名分组,然后会被发送到一个可用的工作者,确保同一组里的所有测试都在同一个工作者中运行。这项功能是在 1.21 版本中添加的。