Skip to content

Commit bebb695

Browse files
authored
Merge pull request #8312 from matthewhughes934/add-regendoc-runs-for-fixture-docs
2 parents 287bab0 + 709c211 commit bebb695

File tree

1 file changed

+82
-27
lines changed

1 file changed

+82
-27
lines changed

doc/en/fixture.rst

Lines changed: 82 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ Fixtures are reusable
375375
^^^^^^^^^^^^^^^^^^^^^
376376

377377
One of the things that makes pytest's fixture system so powerful, is that it
378-
gives us the abilty to define a generic setup step that can reused over and
378+
gives us the ability to define a generic setup step that can reused over and
379379
over, just like a normal function would be used. Two different tests can request
380380
the same fixture and have pytest give each test their own result from that
381381
fixture.
@@ -829,6 +829,8 @@ This system can be leveraged in two ways.
829829
1. ``yield`` fixtures (recommended)
830830
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
831831

832+
.. regendoc: wipe
833+
832834
"Yield" fixtures ``yield`` instead of ``return``. With these
833835
fixtures, we can run some code and pass an object back to the requesting
834836
fixture/test, just like with the other fixtures. The only differences are:
@@ -844,17 +846,48 @@ Once the test is finished, pytest will go back down the list of fixtures, but in
844846
the *reverse order*, taking each one that yielded, and running the code inside
845847
it that was *after* the ``yield`` statement.
846848

847-
As a simple example, let's say we want to test sending email from one user to
848-
another. We'll have to first make each user, then send the email from one user
849-
to the other, and finally assert that the other user received that message in
850-
their inbox. If we want to clean up after the test runs, we'll likely have to
851-
make sure the other user's mailbox is emptied before deleting that user,
852-
otherwise the system may complain.
849+
As a simple example, consider this basic email module:
850+
851+
.. code-block:: python
852+
853+
# content of emaillib.py
854+
class MailAdminClient:
855+
def create_user(self):
856+
return MailUser()
857+
858+
def delete_user(self, user):
859+
# do some cleanup
860+
pass
861+
862+
863+
class MailUser:
864+
def __init__(self):
865+
self.inbox = []
866+
867+
def send_email(self, email, other):
868+
other.inbox.append(email)
869+
870+
def clear_mailbox(self):
871+
self.inbox.clear()
872+
873+
874+
class Email:
875+
def __init__(self, subject, body):
876+
self.subject = subject
877+
self.body = body
878+
879+
Let's say we want to test sending email from one user to another. We'll have to
880+
first make each user, then send the email from one user to the other, and
881+
finally assert that the other user received that message in their inbox. If we
882+
want to clean up after the test runs, we'll likely have to make sure the other
883+
user's mailbox is emptied before deleting that user, otherwise the system may
884+
complain.
853885

854886
Here's what that might look like:
855887

856888
.. code-block:: python
857889
890+
# content of test_emaillib.py
858891
import pytest
859892
860893
from emaillib import Email, MailAdminClient
@@ -869,17 +902,17 @@ Here's what that might look like:
869902
def sending_user(mail_admin):
870903
user = mail_admin.create_user()
871904
yield user
872-
admin_client.delete_user(user)
905+
mail_admin.delete_user(user)
873906
874907
875908
@pytest.fixture
876909
def receiving_user(mail_admin):
877910
user = mail_admin.create_user()
878911
yield user
879-
admin_client.delete_user(user)
912+
mail_admin.delete_user(user)
880913
881914
882-
def test_email_received(sending_user, receiving_user, email):
915+
def test_email_received(sending_user, receiving_user):
883916
email = Email(subject="Hey!", body="How's it going?")
884917
sending_user.send_email(email, receiving_user)
885918
assert email in receiving_user.inbox
@@ -891,6 +924,12 @@ There is a risk that even having the order right on the teardown side of things
891924
doesn't guarantee a safe cleanup. That's covered in a bit more detail in
892925
:ref:`safe teardowns`.
893926

927+
.. code-block:: pytest
928+
929+
$ pytest -q test_emaillib.py
930+
. [100%]
931+
1 passed in 0.12s
932+
894933
Handling errors for yield fixture
895934
"""""""""""""""""""""""""""""""""
896935

@@ -902,7 +941,7 @@ attempt to tear them down as it normally would.
902941
2. Adding finalizers directly
903942
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
904943

905-
While yield fixtures are considered to be the cleaner and more straighforward
944+
While yield fixtures are considered to be the cleaner and more straightforward
906945
option, there is another choice, and that is to add "finalizer" functions
907946
directly to the test's `request-context`_ object. It brings a similar result as
908947
yield fixtures, but requires a bit more verbosity.
@@ -922,6 +961,7 @@ Here's how the previous example would look using the ``addfinalizer`` method:
922961

923962
.. code-block:: python
924963
964+
# content of test_emaillib.py
925965
import pytest
926966
927967
from emaillib import Email, MailAdminClient
@@ -936,15 +976,15 @@ Here's how the previous example would look using the ``addfinalizer`` method:
936976
def sending_user(mail_admin):
937977
user = mail_admin.create_user()
938978
yield user
939-
admin_client.delete_user(user)
979+
mail_admin.delete_user(user)
940980
941981
942982
@pytest.fixture
943983
def receiving_user(mail_admin, request):
944984
user = mail_admin.create_user()
945985
946986
def delete_user():
947-
admin_client.delete_user(user)
987+
mail_admin.delete_user(user)
948988
949989
request.addfinalizer(delete_user)
950990
return user
@@ -956,7 +996,7 @@ Here's how the previous example would look using the ``addfinalizer`` method:
956996
sending_user.send_email(_email, receiving_user)
957997
958998
def empty_mailbox():
959-
receiving_user.delete_email(_email)
999+
receiving_user.clear_mailbox()
9601000
9611001
request.addfinalizer(empty_mailbox)
9621002
return _email
@@ -969,6 +1009,12 @@ Here's how the previous example would look using the ``addfinalizer`` method:
9691009
It's a bit longer than yield fixtures and a bit more complex, but it
9701010
does offer some nuances for when you're in a pinch.
9711011

1012+
.. code-block:: pytest
1013+
1014+
$ pytest -q test_emaillib.py
1015+
. [100%]
1016+
1 passed in 0.12s
1017+
9721018
.. _`safe teardowns`:
9731019

9741020
Safe teardowns
@@ -984,6 +1030,7 @@ above):
9841030

9851031
.. code-block:: python
9861032
1033+
# content of test_emaillib.py
9871034
import pytest
9881035
9891036
from emaillib import Email, MailAdminClient
@@ -995,11 +1042,11 @@ above):
9951042
sending_user = mail_admin.create_user()
9961043
receiving_user = mail_admin.create_user()
9971044
email = Email(subject="Hey!", body="How's it going?")
998-
sending_user.send_emai(email, receiving_user)
1045+
sending_user.send_email(email, receiving_user)
9991046
yield receiving_user, email
1000-
receiving_user.delete_email(email)
1001-
admin_client.delete_user(sending_user)
1002-
admin_client.delete_user(receiving_user)
1047+
receiving_user.clear_mailbox()
1048+
mail_admin.delete_user(sending_user)
1049+
mail_admin.delete_user(receiving_user)
10031050
10041051
10051052
def test_email_received(setup):
@@ -1016,6 +1063,12 @@ One option might be to go with the ``addfinalizer`` method instead of yield
10161063
fixtures, but that might get pretty complex and difficult to maintain (and it
10171064
wouldn't be compact anymore).
10181065

1066+
.. code-block:: pytest
1067+
1068+
$ pytest -q test_emaillib.py
1069+
. [100%]
1070+
1 passed in 0.12s
1071+
10191072
.. _`safe fixture structure`:
10201073

10211074
Safe fixture structure
@@ -1026,7 +1079,7 @@ making one state-changing action each, and then bundling them together with
10261079
their teardown code, as :ref:`the email examples above <yield fixtures>` showed.
10271080

10281081
The chance that a state-changing operation can fail but still modify state is
1029-
neglibible, as most of these operations tend to be `transaction`_-based (at
1082+
negligible, as most of these operations tend to be `transaction`_-based (at
10301083
least at the level of testing where state could be left behind). So if we make
10311084
sure that any successful state-changing action gets torn down by moving it to a
10321085
separate fixture function and separating it from other, potentially failing
@@ -1124,7 +1177,7 @@ never have been made.
11241177
.. _`conftest.py`:
11251178
.. _`conftest`:
11261179

1127-
Fixture availabiility
1180+
Fixture availability
11281181
---------------------
11291182

11301183
Fixture availability is determined from the perspective of the test. A fixture
@@ -1410,9 +1463,9 @@ pytest doesn't know where ``c`` should go in the case, so it should be assumed
14101463
that it could go anywhere between ``g`` and ``b``.
14111464

14121465
This isn't necessarily bad, but it's something to keep in mind. If the order
1413-
they execute in could affect the behavior a test is targetting, or could
1466+
they execute in could affect the behavior a test is targeting, or could
14141467
otherwise influence the result of a test, then the order should be defined
1415-
explicitely in a way that allows pytest to linearize/"flatten" that order.
1468+
explicitly in a way that allows pytest to linearize/"flatten" that order.
14161469

14171470
.. _`autouse order`:
14181471

@@ -1506,7 +1559,7 @@ of what we've gone over so far.
15061559

15071560
All that's needed is stepping up to a larger scope, then having the **act**
15081561
step defined as an autouse fixture, and finally, making sure all the fixtures
1509-
are targetting that highler level scope.
1562+
are targeting that higher level scope.
15101563

15111564
Let's pull :ref:`an example from above <safe fixture structure>`, and tweak it a
15121565
bit. Let's say that in addition to checking for a welcome message in the header,
@@ -1646,7 +1699,7 @@ again, nothing much has changed:
16461699

16471700
.. code-block:: pytest
16481701
1649-
$ pytest -s -q --tb=no
1702+
$ pytest -s -q --tb=no test_module.py
16501703
FFfinalizing <smtplib.SMTP object at 0xdeadbeef> (smtp.gmail.com)
16511704
16521705
========================= short test summary info ==========================
@@ -1777,7 +1830,7 @@ Parametrizing fixtures
17771830
-----------------------------------------------------------------
17781831

17791832
Fixture functions can be parametrized in which case they will be called
1780-
multiple times, each time executing the set of dependent tests, i. e. the
1833+
multiple times, each time executing the set of dependent tests, i.e. the
17811834
tests that depend on this fixture. Test functions usually do not need
17821835
to be aware of their re-running. Fixture parametrization helps to
17831836
write exhaustive functional tests for components which themselves can be
@@ -1931,11 +1984,13 @@ Running the above tests results in the following test IDs being used:
19311984
platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y
19321985
cachedir: $PYTHON_PREFIX/.pytest_cache
19331986
rootdir: $REGENDOC_TMPDIR
1934-
collected 10 items
1987+
collected 11 items
19351988
19361989
<Module test_anothersmtp.py>
19371990
<Function test_showhelo[smtp.gmail.com]>
19381991
<Function test_showhelo[mail.python.org]>
1992+
<Module test_emaillib.py>
1993+
<Function test_email_received>
19391994
<Module test_ids.py>
19401995
<Function test_a[spam]>
19411996
<Function test_a[ham]>
@@ -1947,7 +2002,7 @@ Running the above tests results in the following test IDs being used:
19472002
<Function test_ehlo[mail.python.org]>
19482003
<Function test_noop[mail.python.org]>
19492004
1950-
======================= 10 tests collected in 0.12s ========================
2005+
======================= 11 tests collected in 0.12s ========================
19512006
19522007
.. _`fixture-parametrize-marks`:
19532008

0 commit comments

Comments
 (0)