繁体   English   中英

pytest 是否支持 multiprocessing.set_start_method?

[英]Does pytest support multiprocessing.set_start_method?

multiprocessing.set_start_method的文档指出:

请注意,这应该最多被调用一次,并且应该在主模块的 if name == ' main ' 子句中受到保护。

但是,如果我将multiprocessing.set_start_method('spawn')放在 pytest 模块夹具中,我不知道它是否会完美运行。

确实,如文档中所述,如果尝试从多个单元测试函数调用multiprocessing.set_start_method() ,将会遇到麻烦。 此外,这将影响您的整个程序,并且可能会与整个测试套件严重地互操作。

但是, 在文档中也描述一种解决方法:

另外,您可以使用get_context()获得上下文对象。 上下文对象与多处理模块具有相同的API,并允许一个对象在同一程序中使用多个启动方法。

 import multiprocessing as mp def foo(q): q.put('hello') if __name__ == '__main__': ctx = mp.get_context('spawn') q = ctx.Queue() p = ctx.Process(target=foo, args=(q,)) p.start() print(q.get()) p.join() ``` 

每次测试都可以使用此方法,以避免讨论兼容性问题。 可以将其与“ monkeypatching”或“ mocking”结合使用不同的启动方法来测试您的类:

# my_class.py

import multiprocessing

class MyClass:

    def __init__(self):
        self._queue = multiprocessing.Queue()

    def process(self, x):
        # Very simplified example of a method using a multiprocessing Queue 
        self._queue.put(x)
        return self._queue.get()
# tests/test_my_class.py

import multiprocessing
import my_class

def test_spawn(monkeypatch):
    ctx = multiprocessing.get_context('spawn')
    monkeypatch.setattr(my_class.multiprocessing, "Queue", ctx.Queue)
    obj = my_class.MyClass()
    assert obj.process(6) == 6

def test_fork(monkeypatch):
    ctx = multiprocessing.get_context('fork')
    monkeypatch.setattr(my_class.multiprocessing, "Queue", ctx.Queue)
    obj = my_class.MyClass()
    assert obj.process(6) == 6

如果您确实总是想使用相同的启动方法,则可以在源代码树根目录下的conftest.py文件中的会话范围内设置它。 例如

# conftest.py
import multiprocessing
import pytest

@pytest.fixture(scope="session", autouse=True)
def always_spawn():
    multiprocessing.set_start_method("spawn")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM