You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/source/concepts.rst
+36-13
Original file line number
Diff line number
Diff line change
@@ -4,19 +4,42 @@ Concepts
4
4
5
5
asyncio event loops
6
6
===================
7
-
pytest-asyncio runs each test item in its own asyncio event loop. The loop can be accessed via ``asyncio.get_running_loop()``.
8
-
9
-
.. code-block:: python
10
-
11
-
asyncdeftest_runs_in_a_loop():
12
-
assert asyncio.get_running_loop()
13
-
14
-
Synchronous test functions can get access to an asyncio event loop via the `event_loop` fixture.
15
-
16
-
.. code-block:: python
17
-
18
-
deftest_can_access_current_loop(event_loop):
19
-
assert event_loop
7
+
In order to understand how pytest-asyncio works, it helps to understand how pytest collectors work.
8
+
If you already know about pytest collectors, please :ref:`skip ahead <pytest-asyncio-event-loops>`.
9
+
Otherwise, continue reading.
10
+
Let's assume we have a test suite with a file named *test_all_the_things.py* holding a single test, async or not:
11
+
12
+
.. include:: concepts_function_scope_example.py
13
+
:code: python
14
+
15
+
The file *test_all_the_things.py* is a Python module with a Python test function.
16
+
When we run pytest, the test runner descends into Python packages, modules, and classes, in order to find all tests, regardless whether the tests will run or not.
17
+
This process is referred to as *test collection* by pytest.
18
+
In our particular example, pytest will find our test module and the test function.
19
+
We can visualize the collection result by running ``pytest --collect-only``::
20
+
21
+
<Module test_all_the_things.py>
22
+
<Function test_runs_in_a_loop>
23
+
24
+
The example illustrates that the code of our test suite is hierarchical.
25
+
Pytest uses so called *collectors* for each level of the hierarchy.
26
+
Our contrived example test suite uses the *Module* and *Function* collectors, but real world test code may contain additional hierarchy levels via the *Package* or *Class* collectors.
27
+
There's also a special *Session* collector at the root of the hierarchy.
28
+
You may notice that the individual levels resemble the possible `scopes of a pytest fixture. <https://docs.pytest.org/en/7.4.x/how-to/fixtures.html#scope-sharing-fixtures-across-classes-modules-packages-or-session>`__
29
+
30
+
.. _pytest-asyncio-event-loops:
31
+
Pytest-asyncio provides one asyncio event loop for each pytest collector.
32
+
By default, each test runs in the event loop provided by the *Function* collector, i.e. tests use the loop with the narrowest scope.
33
+
This gives the highest level of isolation between tests.
34
+
If two or more tests share a common ancestor collector, the tests can be configured to run in their ancestor's loop by passing the appropriate *scope* keyword argument to the *asyncio* mark.
35
+
For example, the following two tests use the asyncio event loop provided by the *Module* collector:
36
+
37
+
.. include:: concepts_module_scope_example.py
38
+
:code: python
39
+
40
+
It's highly recommended for neighboring tests to use the same event loop scope.
41
+
For example, all tests in a class or module should use the same scope.
42
+
Assigning neighboring tests to different event loop scopes is discouraged as it can make test code hard to follow.
0 commit comments