为什么要在工厂功能上使用pytest工厂作为固定装置?

cod*_*ded 3 python unit-testing fixture pytest

py.test文档中,它描述了将工厂方法声明为fixture,例如:

@pytest.fixture
def make_foo():
    def __make_foo(name):
        foo = Foo()
        foo.name = name
        return foo
    return __make_foo
Run Code Online (Sandbox Code Playgroud)

与仅定义make_foo函数并使用它相比,这样做有什么好处/缺点?我不明白为什么它是固定装置。

Aiv*_*ven 7

如果您有许多简单的工厂,那么您可以使用装饰器简化它们的创建:

def factory_fixture(factory):
    @pytest.fixture(scope='session')
    def maker():
        return factory

    maker.__name__ = factory.__name__
    return maker


@factory_fixture
def make_stuff(foo, bar):
    return 'foo' + str(foo + bar)
Run Code Online (Sandbox Code Playgroud)

这相当于

@pytest.fixture(score='session')
def make_stuff():
    def make(foo, bar):
        return 'foo' + str(foo + bar)
    return
Run Code Online (Sandbox Code Playgroud)


rsa*_*mei 5

实际上,最重要的优点是能够使用其他固定装置,并为您提供pytest的依赖项注入。另一个优点是允许您将参数传递给工厂,而这些参数在普通灯具中必须是静态的。

看这个例子:

@pytest.fixture
def mocked_server():
    with mock.patch('something'):
        yield MyServer()


@pytest.fixture
def connected_client(mocked_server):
    client = Client()
    client.connect_to(mocked_server, local_port=123)  # local_port must be static
    return client
Run Code Online (Sandbox Code Playgroud)

您现在可以编写一个测试,获得 connected_client,但不能更改端口。如果您需要与多个客户进行测试该怎么办?你也不能。

如果您现在写:

@pytest.fixture
def connect_client(mocked_server):
    def __connect(local_port):
        client = Client()
        client.connect_to(mocked_server, local_port)
        return client
    return __connect
Run Code Online (Sandbox Code Playgroud)

现在,您可以编写一个接收connect_client工厂的测试,然后调用该测试以在任何端口获取您想要的初始化客户端,以及您需要多少次!

  • 这显示了工厂夹具相对于普通夹具的优势,但是如何显示工厂夹具相对于工厂功能的优势呢? (4认同)