summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/tools/pytest/doc/en/yieldfixture.rst
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/tools/pytest/doc/en/yieldfixture.rst')
-rw-r--r--testing/web-platform/tests/tools/pytest/doc/en/yieldfixture.rst100
1 files changed, 100 insertions, 0 deletions
diff --git a/testing/web-platform/tests/tools/pytest/doc/en/yieldfixture.rst b/testing/web-platform/tests/tools/pytest/doc/en/yieldfixture.rst
new file mode 100644
index 000000000..ee88a27df
--- /dev/null
+++ b/testing/web-platform/tests/tools/pytest/doc/en/yieldfixture.rst
@@ -0,0 +1,100 @@
+.. _yieldfixture:
+
+Fixture functions using "yield" / context manager integration
+---------------------------------------------------------------
+
+.. versionadded:: 2.4
+
+.. regendoc:wipe
+
+pytest-2.4 allows fixture functions to seamlessly use a ``yield`` instead
+of a ``return`` statement to provide a fixture value while otherwise
+fully supporting all other fixture features.
+
+Let's look at a simple standalone-example using the ``yield`` syntax::
+
+ # content of test_yield.py
+
+ import pytest
+
+ @pytest.yield_fixture
+ def passwd():
+ print ("\nsetup before yield")
+ f = open("/etc/passwd")
+ yield f.readlines()
+ print ("teardown after yield")
+ f.close()
+
+ def test_has_lines(passwd):
+ print ("test called")
+ assert passwd
+
+In contrast to :ref:`finalization through registering callbacks
+<finalization>`, our fixture function used a ``yield``
+statement to provide the lines of the ``/etc/passwd`` file.
+The code after the ``yield`` statement serves as the teardown code,
+avoiding the indirection of registering a teardown callback function.
+
+Let's run it with output capturing disabled::
+
+ $ py.test -q -s test_yield.py
+
+ setup before yield
+ test called
+ .teardown after yield
+
+ 1 passed in 0.12 seconds
+
+We can also seamlessly use the new syntax with ``with`` statements.
+Let's simplify the above ``passwd`` fixture::
+
+ # content of test_yield2.py
+
+ import pytest
+
+ @pytest.yield_fixture
+ def passwd():
+ with open("/etc/passwd") as f:
+ yield f.readlines()
+
+ def test_has_lines(passwd):
+ assert len(passwd) >= 1
+
+The file ``f`` will be closed after the test finished execution
+because the Python ``file`` object supports finalization when
+the ``with`` statement ends.
+
+Note that the yield fixture form supports all other fixture
+features such as ``scope``, ``params``, etc., thus changing existing
+fixture functions to use ``yield`` is straightforward.
+
+.. note::
+
+ While the ``yield`` syntax is similar to what
+ :py:func:`contextlib.contextmanager` decorated functions
+ provide, with pytest fixture functions the part after the
+ "yield" will always be invoked, independently from the
+ exception status of the test function which uses the fixture.
+ This behaviour makes sense if you consider that many different
+ test functions might use a module or session scoped fixture.
+
+
+Discussion and future considerations / feedback
+++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+There are some topics that are worth mentioning:
+
+- usually ``yield`` is used for producing multiple values.
+ But fixture functions can only yield exactly one value.
+ Yielding a second fixture value will get you an error.
+ It's possible we can evolve pytest to allow for producing
+ multiple values as an alternative to current parametrization.
+ For now, you can just use the normal
+ :ref:`fixture parametrization <fixture-parametrize>`
+ mechanisms together with ``yield``-style fixtures.
+
+- lastly ``yield`` introduces more than one way to write
+ fixture functions, so what's the obvious way to a newcomer?
+
+If you want to feedback or participate in discussion of the above
+topics, please join our :ref:`contact channels`, you are most welcome.