Actually, the most important advantage is being able to use other fixtures, and make the dependency injection of pytest work for you.
The other advantage is allowing you to pass parameters to the factory, which would have to be static in a normal fixture.
Look at this example:
@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
You could now write a test that gets a connected_client
, but you can't change the port.
What if you need a test with multiple clients? You can't either.
If you now write:
@pytest.fixture
def connect_client(mocked_server):
def __connect(local_port):
client = Client()
client.connect_to(mocked_server, local_port)
return client
return __connect
You get to write tests receiving a connect_client
factory, and call it to get an initialized client in any port, and how many times you want!
yield
fixtures (or ones that add the finalizer hooks torequest
), so you can rollback any changes the factory did throughout the test execution. These benefits are not factory specific and apply to any test helper function that could be replaced by a fixture. – Thinker