difference between fixture and yield_fixture in pytest
Question:
I am going through pytest fixtures, and the following looks pretty similar, latest works pretty similar.
Yes, the readability is better in yield_fixure, however could someone let me know what exactly is the difference.
which should I use, in cases like mentioned below?
@pytest.fixture()
def open_browser(request):
print("Browser opened")
def close_browser():
print("browser closed")
request.addfinalizer(close_browser)
return "browser object"
@pytest.yield_fixture()
def open_browser():
print("Browser opened")
yield "browser object"
print("browser closed")
def test_google_search(open_browser):
print(open_browser)
print("test_google_search")
Answers:
The only difference is in readability. I think (though I’m not 100% sure) the underlying behavior is identical (i.e. the cleanup after the yield
statement is run as a finalizer). I always prefer using yield fixtures for cleanup, since it’s more readable.
If you’re using pytest <3.0, you’ll still need to use pytest.yield_fixture
to get that behavior. But if you’re able to use pytest 3.0+, pytest.yield_fixture
is deprecated and you can use pytest.fixture
to get the same yield_fixture
behavior.
Here are the explanatory docs:
Since pytest-3.0, fixtures using the normal fixture decorator can use
a yield statement to provide fixture values and execute teardown code,
exactly like yield_fixture in previous versions.
Marking functions as yield_fixture is still supported, but deprecated
and should not be used in new code.
addfinalizer
has two key differences over yield:
- It is possible to register multiple finalizer functions.
- Finalizers will always be called regardless if the fixture setup
code raises an exception. This is handy to properly close all
resources created by a fixture even if one of them fails to be
created/acquired
From the pytest docs
I am going through pytest fixtures, and the following looks pretty similar, latest works pretty similar.
Yes, the readability is better in yield_fixure, however could someone let me know what exactly is the difference.
which should I use, in cases like mentioned below?
@pytest.fixture()
def open_browser(request):
print("Browser opened")
def close_browser():
print("browser closed")
request.addfinalizer(close_browser)
return "browser object"
@pytest.yield_fixture()
def open_browser():
print("Browser opened")
yield "browser object"
print("browser closed")
def test_google_search(open_browser):
print(open_browser)
print("test_google_search")
The only difference is in readability. I think (though I’m not 100% sure) the underlying behavior is identical (i.e. the cleanup after the yield
statement is run as a finalizer). I always prefer using yield fixtures for cleanup, since it’s more readable.
If you’re using pytest <3.0, you’ll still need to use pytest.yield_fixture
to get that behavior. But if you’re able to use pytest 3.0+, pytest.yield_fixture
is deprecated and you can use pytest.fixture
to get the same yield_fixture
behavior.
Here are the explanatory docs:
Since pytest-3.0, fixtures using the normal fixture decorator can use
a yield statement to provide fixture values and execute teardown code,
exactly like yield_fixture in previous versions.Marking functions as yield_fixture is still supported, but deprecated
and should not be used in new code.
addfinalizer
has two key differences over yield:
- It is possible to register multiple finalizer functions.
- Finalizers will always be called regardless if the fixture setup
code raises an exception. This is handy to properly close all
resources created by a fixture even if one of them fails to be
created/acquired
From the pytest docs