有没有办法控制 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 开始执行并行但测试套件中的各个测试需要串行执行。
当我使用 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-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,))
I have the following directory layout:
runner.py
lib/
tests/
testsuite1/
testsuite1.py
testsuite2/
testsuite2.py
testsuite3/
testsuite3.py
testsuite4/
testsuite4.py
The format of testsuite*.py modules is as follows:
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__)])
The problem I have is that I would like to execute the 'testsuites' in parallel i.e. I want testsuite1, testsuite2, testsuite3 and testsuite4 to start execution in parallel but individual tests within the testsuites need to be executed serially.
When I use the 'xdist' plugin from py.test and kick off the tests using 'py.test -n 4', py.test is gathering all the tests and randomly load balancing the tests among 4 workers. This leads to the 'setup_class' method to be executed every time of each test within a 'testsuitex.py' module (which defeats my purpose. I want setup_class to be executed only once per class and tests executed serially there after).
Essentially what I want the execution to look like is:
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
while worker1, worker2, worker3 and worker4
are all executed in parallel.
Is there a way to achieve this in 'pytest-xidst' framework?
The only option that I can think of is to kick off different processes to execute each test suite individually within 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,))
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以使用
--dist=loadscope
将所有测试分组到同一测试类中。这是来自 pypi 上的 pytest-xdist 的文档You can use
--dist=loadscope
to group all the tests in the same test class. Here is the doc from pytest-xdist on pypi多个选项可用 是
的,有这样的方法,每个 xdist 版本
1.28.0
的可用选项如下:--dist=each
:将所有测试发送给所有节点,因此每个测试都在每个节点上运行。--dist=load
:将收集的测试分布到所有节点,以便每个测试仅运行一次。所有节点收集并提交测试套件并
当收到(测试套件的)所有集合时,将验证它们是
相同的集合。然后集合被分为
块和块被提交到节点执行。
--dist=loadscope
将收集的测试分布到所有节点,以便运行每个测试就一次。所有节点收集并提交测试列表,当所有节点
收到藏品后,经验证它们是相同的藏品。
然后集合被划分为工作单元,并按测试范围分组,
这些工作单元被提交给节点。
--dist=loadfile
将收集的测试分布到所有节点,以便运行每个测试就一次。所有节点收集并提交测试列表,当所有节点
收到藏品后,经验证它们是相同的藏品。
然后集合被划分为工作单元,并按测试文件分组,
这些工作单元被提交给节点。
如果您需要任何进一步的信息,我建议您直接进入 调度程序的实际实现并检查分配是如何完成的。
Multiple Options Available
Yes, there are such ways, the available options per xdist version
1.28.0
is the following ones:--dist=each
: Sends all the tests to all the nodes, so each test is run on every node.--dist=load
: Distributes the tests collected across all nodes so each testis run just once. All nodes collect and submit the test suite and
when all collections (of test suites) are received it is verified they are
identical collections. Then the collection gets divided up in
chunks and chunks get submitted to nodes for execution.
--dist=loadscope
Distributes the tests collected across all nodes so each test is runjust once. All nodes collect and submit the list of tests and when all
collections are received it is verified they are identical collections.
Then the collection gets divided up in work units, grouped by test scope,
and those work units get submitted to nodes.
--dist=loadfile
Distributes the tests collected across all nodes so each test is runjust once. All nodes collect and submit the list of tests and when all
collections are received it is verified they are identical collections.
Then the collection gets divided up in work units, grouped by test file,
and those work units get submitted to nodes.
If you need any further information I recommend you to go straightly into the actual implementation of the schedulers and checkout how the distribution is being done.
对于 pytest-xdist,目前没有任何类型的“每个文件”或“每个测试套件”分发。实际上,如果每个文件的分发(例如,文件中的测试一次最多只能由一个工作人员执行)已经对您的用例有所帮助,我鼓励您使用 pytest 问题跟踪器在 https://bitbucket.org/hpk42/pytest/issues?status=new&status=打开并链接回您的良好解释。
干杯,霍尔格
With pytest-xdist there currently no kind of "per-file" or "per-test-suite" distribution. Actually, if a per-file distribution (e.g. tests in a file will be only executed by at most one worker at a time) would already help your use case i encourage you to file a feature issue with the pytest issue tracker at https://bitbucket.org/hpk42/pytest/issues?status=new&status=open and link back to your good explanation here.
cheers,holger
pytest_mproc(https://nak.github.io/pytest_mproc_docs/index.html)提供了一个“组”装饰器,允许您将测试分组在一起以串行执行。当处理大量内核时,它的启动时间也比 xdist 更快,并提供“全局”范围的测试装置。
pytest_mproc (https://nak.github.io/pytest_mproc_docs/index.html) provides a "group" decorator that allows you to group tests together for execution serially. It also has faster startup time when working on large numbers of cores than xdist and provides a "global" scope test fixture.
将测试套件放在像问题一样的目录中,您可以通过以下方式并行运行它们:
如果您的测试套件文件位于单个目录中,那么万一
出现新的套件文件,这将自动包含新的测试文件,并将添加额外的工作人员为了它
Having test suites in directory like in the question, you can run them in parallel it via:
If you have your tests suite files in single directory then just
In case new suite file occurs, this will include new test file automatically and will add additional worker for it
还值得注意的是 pytest-xdist 上的此问题 github 解决了我认为您在这里询问的用例。
由于该问题尚未解决(尽管已于 2015 年提出),我只是为我的具体案例修补了一个可行的解决方案。在我的 conftest.py 中,我添加了这段代码:
它基本上只是覆盖 xdist 中的 _split_scope 函数,以按节点 ID 而不是按文件类型分割组。它对我有用,但我无法保证稳健性,因为我们正在对一些通常的内部代码进行猴子修补;使用风险由您自行承担。
It may also be worth noting that this issue on the pytest-xdist github addresses the use case I think you're asking about here.
Since the issue hasn't yet been resolved (despite being opened in 2015), I just monkey-patched a workable solution for my specific case. In my conftest.py, I added this chunk of code:
It basically just overwrites the _split_scope function from xdist to split groups by the nodeid instead of by the filetype. It worked for me, but I can't guarentee robustness since we're monkey-patching some normally internal code; use at your own risk.