1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
from __future__ import annotations
from textwrap import dedent
from pytest import Pytester
def test_event_loop_fixture_finalizer_returns_fresh_loop_after_test(pytester: Pytester):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
dedent(
"""\
import asyncio
import pytest
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
@pytest.mark.asyncio
async def test_1():
# This async test runs in its own event loop
global loop
running_loop = asyncio.get_event_loop_policy().get_event_loop()
# Make sure this test case received a different loop
assert running_loop is not loop
def test_2():
# Code outside of pytest-asyncio should not receive a "used" event loop
current_loop = asyncio.get_event_loop_policy().get_event_loop()
assert not current_loop.is_running()
assert not current_loop.is_closed()
"""
)
)
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(passed=2)
def test_event_loop_fixture_finalizer_handles_loop_set_to_none_sync(
pytester: Pytester,
):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
dedent(
"""\
import asyncio
def test_sync(event_loop):
asyncio.get_event_loop_policy().set_event_loop(None)
"""
)
)
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(passed=1)
def test_event_loop_fixture_finalizer_handles_loop_set_to_none_async_without_fixture(
pytester: Pytester,
):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
dedent(
"""\
import asyncio
import pytest
@pytest.mark.asyncio
async def test_async_without_explicit_fixture_request():
asyncio.get_event_loop_policy().set_event_loop(None)
"""
)
)
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(passed=1)
def test_event_loop_fixture_finalizer_handles_loop_set_to_none_async_with_fixture(
pytester: Pytester,
):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
dedent(
"""\
import asyncio
import pytest
@pytest.mark.asyncio
async def test_async_with_explicit_fixture_request(event_loop):
asyncio.get_event_loop_policy().set_event_loop(None)
"""
)
)
result = pytester.runpytest_subprocess("--asyncio-mode=strict", "-W default")
result.assert_outcomes(passed=1, warnings=1)
result.stdout.fnmatch_lines(
'*is asynchronous and explicitly requests the "event_loop" fixture*'
)
def test_event_loop_fixture_finalizer_raises_warning_when_fixture_leaves_loop_unclosed(
pytester: Pytester,
):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
dedent(
"""\
import asyncio
import pytest
pytest_plugins = 'pytest_asyncio'
@pytest.fixture
def event_loop():
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
@pytest.mark.asyncio
async def test_ends_with_unclosed_loop():
pass
"""
)
)
result = pytester.runpytest_subprocess("--asyncio-mode=strict", "-W", "default")
result.assert_outcomes(passed=1, warnings=2)
result.stdout.fnmatch_lines("*unclosed event loop*")
def test_event_loop_fixture_finalizer_raises_warning_when_test_leaves_loop_unclosed(
pytester: Pytester,
):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
dedent(
"""\
import asyncio
import pytest
pytest_plugins = 'pytest_asyncio'
@pytest.mark.asyncio
async def test_ends_with_unclosed_loop():
asyncio.set_event_loop(asyncio.new_event_loop())
"""
)
)
result = pytester.runpytest_subprocess("--asyncio-mode=strict", "-W", "default")
result.assert_outcomes(passed=1, warnings=1)
result.stdout.fnmatch_lines("*unclosed event loop*")
|