From c4b3585a690aa94b424b8992a87a192fc0364cea Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Sun, 15 Jan 2023 12:27:58 +0100 Subject: [PATCH 1/3] [docs] Split up the reference section into different documents, one for each topic. Signed-off-by: Michael Seifert --- docs/source/index.rst | 2 +- docs/source/reference.rst | 145 ------------------------ docs/source/reference/configuration.rst | 21 ++++ docs/source/reference/decorators.rst | 27 +++++ docs/source/reference/fixtures.rst | 58 ++++++++++ docs/source/reference/index.rst | 13 +++ docs/source/reference/markers.rst | 34 ++++++ 7 files changed, 154 insertions(+), 146 deletions(-) delete mode 100644 docs/source/reference.rst create mode 100644 docs/source/reference/configuration.rst create mode 100644 docs/source/reference/decorators.rst create mode 100644 docs/source/reference/fixtures.rst create mode 100644 docs/source/reference/index.rst create mode 100644 docs/source/reference/markers.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index 153fe9e8..618e6e6f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -7,7 +7,7 @@ Welcome to pytest-asyncio! :hidden: concepts - reference + reference/index support pytest-asyncio is a `pytest `_ plugin. It facilitates testing of code that uses the `asyncio `_ library. diff --git a/docs/source/reference.rst b/docs/source/reference.rst deleted file mode 100644 index 2fa77ff4..00000000 --- a/docs/source/reference.rst +++ /dev/null @@ -1,145 +0,0 @@ -========= -Reference -========= - -Configuration -============= - -The pytest-asyncio mode can be set by the ``asyncio_mode`` configuration option in the `configuration file -`_: - -.. code-block:: ini - - # pytest.ini - [pytest] - asyncio_mode = auto - -The value can also be set via the ``--asyncio-mode`` command-line option: - -.. code-block:: bash - - $ pytest tests --asyncio-mode=strict - - -If the asyncio mode is set in both the pytest configuration file and the command-line option, the command-line option takes precedence. If no asyncio mode is specified, the mode defaults to `strict`. - -Fixtures -======== - -``event_loop`` --------------- -Creates a new asyncio event loop based on the current event loop policy. The new loop -is available as the return value of this fixture or via `asyncio.get_running_loop `__. -The event loop is closed when the fixture scope ends. The fixture scope defaults -to ``function`` scope. - -.. code-block:: python - - def test_http_client(event_loop): - url = "http://httpbin.org/get" - resp = event_loop.run_until_complete(http_client(url)) - assert b"HTTP/1.1 200 OK" in resp - -Note that, when using the ``event_loop`` fixture, you need to interact with the event loop using methods like ``event_loop.run_until_complete``. If you want to *await* code inside your test function, you need to write a coroutine and use it as a test function. The `asyncio <#pytest-mark-asyncio>`__ marker -is used to mark coroutines that should be treated as test functions. - -The ``event_loop`` fixture can be overridden in any of the standard pytest locations, -e.g. directly in the test file, or in ``conftest.py``. This allows redefining the -fixture scope, for example: - -.. code-block:: python - - @pytest.fixture(scope="session") - def event_loop(): - policy = asyncio.get_event_loop_policy() - loop = policy.new_event_loop() - yield loop - loop.close() - -If you need to change the type of the event loop, prefer setting a custom event loop policy over redefining the ``event_loop`` fixture. - -If the ``pytest.mark.asyncio`` decorator is applied to a test function, the ``event_loop`` -fixture will be requested automatically by the test function. - -``unused_tcp_port`` -------------------- -Finds and yields a single unused TCP port on the localhost interface. Useful for -binding temporary test servers. - -``unused_tcp_port_factory`` ---------------------------- -A callable which returns a different unused TCP port each invocation. Useful -when several unused TCP ports are required in a test. - -.. code-block:: python - - def a_test(unused_tcp_port_factory): - port1, port2 = unused_tcp_port_factory(), unused_tcp_port_factory() - ... - -``unused_udp_port`` and ``unused_udp_port_factory`` ---------------------------------------------------- -Works just like their TCP counterparts but returns unused UDP ports. - - -Markers -======= - -``pytest.mark.asyncio`` ------------------------ -A coroutine or async generator with this marker will be treated as a test function by pytest. The marked function will be executed as an -asyncio task in the event loop provided by the ``event_loop`` fixture. - -In order to make your test code a little more concise, the pytest |pytestmark|_ -feature can be used to mark entire modules or classes with this marker. -Only test coroutines will be affected (by default, coroutines prefixed by -``test_``), so, for example, fixtures are safe to define. - -.. code-block:: python - - import asyncio - - import pytest - - # All test coroutines will be treated as marked. - pytestmark = pytest.mark.asyncio - - - async def test_example(event_loop): - """No marker!""" - await asyncio.sleep(0, loop=event_loop) - -In *auto* mode, the ``pytest.mark.asyncio`` marker can be omitted, the marker is added -automatically to *async* test functions. - - -.. |pytestmark| replace:: ``pytestmark`` -.. _pytestmark: http://doc.pytest.org/en/latest/example/markers.html#marking-whole-classes-or-modules - - -Decorators -========== -Asynchronous fixtures are defined just like ordinary pytest fixtures, except they should be decorated with ``@pytest_asyncio.fixture``. - -.. code-block:: python3 - - import pytest_asyncio - - - @pytest_asyncio.fixture - async def async_gen_fixture(): - await asyncio.sleep(0.1) - yield "a value" - - - @pytest_asyncio.fixture(scope="module") - async def async_fixture(): - return await asyncio.sleep(0.1) - -All scopes are supported, but if you use a non-function scope you will need -to redefine the ``event_loop`` fixture to have the same or broader scope. -Async fixtures need the event loop, and so must have the same or narrower scope -than the ``event_loop`` fixture. - -*auto* mode automatically converts async fixtures declared with the -standard ``@pytest.fixture`` decorator to *asyncio-driven* versions. diff --git a/docs/source/reference/configuration.rst b/docs/source/reference/configuration.rst new file mode 100644 index 00000000..5d840c47 --- /dev/null +++ b/docs/source/reference/configuration.rst @@ -0,0 +1,21 @@ +============= +Configuration +============= + +The pytest-asyncio mode can be set by the ``asyncio_mode`` configuration option in the `configuration file +`_: + +.. code-block:: ini + + # pytest.ini + [pytest] + asyncio_mode = auto + +The value can also be set via the ``--asyncio-mode`` command-line option: + +.. code-block:: bash + + $ pytest tests --asyncio-mode=strict + + +If the asyncio mode is set in both the pytest configuration file and the command-line option, the command-line option takes precedence. If no asyncio mode is specified, the mode defaults to `strict`. diff --git a/docs/source/reference/decorators.rst b/docs/source/reference/decorators.rst new file mode 100644 index 00000000..977ed6b8 --- /dev/null +++ b/docs/source/reference/decorators.rst @@ -0,0 +1,27 @@ +========== +Decorators +========== +Asynchronous fixtures are defined just like ordinary pytest fixtures, except they should be decorated with ``@pytest_asyncio.fixture``. + +.. code-block:: python3 + + import pytest_asyncio + + + @pytest_asyncio.fixture + async def async_gen_fixture(): + await asyncio.sleep(0.1) + yield "a value" + + + @pytest_asyncio.fixture(scope="module") + async def async_fixture(): + return await asyncio.sleep(0.1) + +All scopes are supported, but if you use a non-function scope you will need +to redefine the ``event_loop`` fixture to have the same or broader scope. +Async fixtures need the event loop, and so must have the same or narrower scope +than the ``event_loop`` fixture. + +*auto* mode automatically converts async fixtures declared with the +standard ``@pytest.fixture`` decorator to *asyncio-driven* versions. diff --git a/docs/source/reference/fixtures.rst b/docs/source/reference/fixtures.rst new file mode 100644 index 00000000..fdd3e034 --- /dev/null +++ b/docs/source/reference/fixtures.rst @@ -0,0 +1,58 @@ +======== +Fixtures +======== + +``event_loop`` +============== +Creates a new asyncio event loop based on the current event loop policy. The new loop +is available as the return value of this fixture or via `asyncio.get_running_loop `__. +The event loop is closed when the fixture scope ends. The fixture scope defaults +to ``function`` scope. + +.. code-block:: python + + def test_http_client(event_loop): + url = "http://httpbin.org/get" + resp = event_loop.run_until_complete(http_client(url)) + assert b"HTTP/1.1 200 OK" in resp + +Note that, when using the ``event_loop`` fixture, you need to interact with the event loop using methods like ``event_loop.run_until_complete``. If you want to *await* code inside your test function, you need to write a coroutine and use it as a test function. The `asyncio <#pytest-mark-asyncio>`__ marker +is used to mark coroutines that should be treated as test functions. + +The ``event_loop`` fixture can be overridden in any of the standard pytest locations, +e.g. directly in the test file, or in ``conftest.py``. This allows redefining the +fixture scope, for example: + +.. code-block:: python + + @pytest.fixture(scope="session") + def event_loop(): + policy = asyncio.get_event_loop_policy() + loop = policy.new_event_loop() + yield loop + loop.close() + +If you need to change the type of the event loop, prefer setting a custom event loop policy over redefining the ``event_loop`` fixture. + +If the ``pytest.mark.asyncio`` decorator is applied to a test function, the ``event_loop`` +fixture will be requested automatically by the test function. + +``unused_tcp_port`` +=================== +Finds and yields a single unused TCP port on the localhost interface. Useful for +binding temporary test servers. + +``unused_tcp_port_factory`` +=========================== +A callable which returns a different unused TCP port each invocation. Useful +when several unused TCP ports are required in a test. + +.. code-block:: python + + def a_test(unused_tcp_port_factory): + port1, port2 = unused_tcp_port_factory(), unused_tcp_port_factory() + ... + +``unused_udp_port`` and ``unused_udp_port_factory`` +=================================================== +Works just like their TCP counterparts but returns unused UDP ports. diff --git a/docs/source/reference/index.rst b/docs/source/reference/index.rst new file mode 100644 index 00000000..52ce7a0b --- /dev/null +++ b/docs/source/reference/index.rst @@ -0,0 +1,13 @@ +========= +Reference +========= + +.. toctree:: + :hidden: + + configuration + fixtures + markers + decorators + +This section of the documentation provides descriptions of the individual parts provided by pytest-asyncio. diff --git a/docs/source/reference/markers.rst b/docs/source/reference/markers.rst new file mode 100644 index 00000000..eb89592c --- /dev/null +++ b/docs/source/reference/markers.rst @@ -0,0 +1,34 @@ +======= +Markers +======= + +``pytest.mark.asyncio`` +======================= +A coroutine or async generator with this marker will be treated as a test function by pytest. The marked function will be executed as an +asyncio task in the event loop provided by the ``event_loop`` fixture. + +In order to make your test code a little more concise, the pytest |pytestmark|_ +feature can be used to mark entire modules or classes with this marker. +Only test coroutines will be affected (by default, coroutines prefixed by +``test_``), so, for example, fixtures are safe to define. + +.. code-block:: python + + import asyncio + + import pytest + + # All test coroutines will be treated as marked. + pytestmark = pytest.mark.asyncio + + + async def test_example(event_loop): + """No marker!""" + await asyncio.sleep(0, loop=event_loop) + +In *auto* mode, the ``pytest.mark.asyncio`` marker can be omitted, the marker is added +automatically to *async* test functions. + + +.. |pytestmark| replace:: ``pytestmark`` +.. _pytestmark: http://doc.pytest.org/en/latest/example/markers.html#marking-whole-classes-or-modules From 6b5413d585c0f62e06b4d23a6fc00945b8efcc56 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Sun, 15 Jan 2023 12:29:12 +0100 Subject: [PATCH 2/3] [docs] Move CHANGELOG from project root to user documentation. Signed-off-by: Michael Seifert --- MANIFEST.in | 2 -- CHANGELOG.rst => docs/source/reference/changelog.rst | 0 docs/source/reference/index.rst | 2 ++ 3 files changed, 2 insertions(+), 2 deletions(-) rename CHANGELOG.rst => docs/source/reference/changelog.rst (100%) diff --git a/MANIFEST.in b/MANIFEST.in index fdf813e9..6bd245e1 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,3 @@ -include CHANGELOG.rst - recursive-exclude .github * exclude .gitignore exclude .pre-commit-config.yaml diff --git a/CHANGELOG.rst b/docs/source/reference/changelog.rst similarity index 100% rename from CHANGELOG.rst rename to docs/source/reference/changelog.rst diff --git a/docs/source/reference/index.rst b/docs/source/reference/index.rst index 52ce7a0b..c07d0e19 100644 --- a/docs/source/reference/index.rst +++ b/docs/source/reference/index.rst @@ -9,5 +9,7 @@ Reference fixtures markers decorators + changelog This section of the documentation provides descriptions of the individual parts provided by pytest-asyncio. +The reference section also provides a chronological list of changes for each release. From 0e249c898260f71b6e2bce171b0219400cbb5ce1 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Sun, 15 Jan 2023 12:37:08 +0100 Subject: [PATCH 3/3] [build] Add links to documentation, changelog, and bug tracker to the project URLs. Signed-off-by: Michael Seifert --- setup.cfg | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 04ea3d90..a82c57e1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,7 +3,10 @@ name = pytest-asyncio version = attr: pytest_asyncio.__version__ url = https://github.com/pytest-dev/pytest-asyncio project_urls = - GitHub = https://github.com/pytest-dev/pytest-asyncio + Documentation = https://pytest-asyncio.readthedocs.io + Changelog = https://pytest-asyncio.readthedocs.io/en/latest/reference/changelog.html + Source Code = https://github.com/pytest-dev/pytest-asyncio + Bug Tracker = https://github.com/pytest-dev/pytest-asyncio/issues description = Pytest support for asyncio long_description = file: README.rst long_description_content_type = text/x-rst