Skip to content

Commit 6d10627

Browse files
committed
Merge branch 'docs' of github.com:njsmith/pytest-trio into docs
2 parents 8ed0092 + 2a06e23 commit 6d10627

17 files changed

Lines changed: 892 additions & 214 deletions

ci/rtd-requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@
22
sphinx >= 1.6.1
33
sphinx_rtd_theme
44
sphinxcontrib-trio
5+
# Workaround for this weird issue:
6+
# https://travis-ci.org/python-trio/pytest-trio/jobs/407495415
7+
attrs >= 17.4.0

pytest_trio/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
"""Top-level package for pytest-trio."""
22

33
from ._version import __version__
4+
from .plugin import trio_fixture
5+
6+
__all__ = ["trio_fixture"]

pytest_trio/_tests/helpers.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import pytest
2+
3+
4+
def enable_trio_mode_via_pytest_ini(testdir):
5+
testdir.makefile(".ini", pytest="[pytest]\ntrio_mode = true\n")
6+
7+
8+
def enable_trio_mode_via_conftest_py(testdir):
9+
testdir.makeconftest("from pytest_trio.enable_trio_mode import *")
10+
11+
12+
enable_trio_mode = pytest.mark.parametrize(
13+
"enable_trio_mode",
14+
[enable_trio_mode_via_pytest_ini, enable_trio_mode_via_conftest_py]
15+
)

pytest_trio/_tests/test_async_yield_fixture.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -317,39 +317,43 @@ def test_async_yield_fixture_crashed_teardown_allow_other_teardowns(
317317
import trio
318318
from async_generator import async_generator, yield_
319319
320-
events = []
320+
setup_events = set()
321+
teardown_events = set()
321322
322323
@pytest.fixture
323324
@async_generator
324325
async def good_fixture():
325326
async with trio.open_nursery() as nursery:
326-
events.append('good_fixture setup')
327+
setup_events.add('good_fixture setup')
327328
await yield_(None)
328-
events.append('good_fixture teardown')
329+
teardown_events.add('good_fixture teardown')
329330
330331
@pytest.fixture
331332
@async_generator
332333
async def bad_fixture():
333334
async with trio.open_nursery() as nursery:
334-
events.append('bad_fixture setup')
335+
setup_events.add('bad_fixture setup')
335336
await yield_(None)
336-
events.append('bad_fixture teardown')
337+
teardown_events.add('bad_fixture teardown')
337338
raise RuntimeError('Crash during fixture teardown')
338339
339340
def test_before():
340-
assert not events
341+
assert not setup_events
342+
assert not teardown_events
341343
342344
@pytest.mark.trio
343345
async def test_actual_test(bad_fixture, good_fixture):
344346
pass
345347
346348
def test_after():
347-
assert events == [
349+
assert setup_events == {
348350
'good_fixture setup',
349351
'bad_fixture setup',
352+
}
353+
assert teardown_events == {
350354
'bad_fixture teardown',
351355
'good_fixture teardown',
352-
]
356+
}
353357
"""
354358
)
355359
)

pytest_trio/_tests/test_basic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def test_check_async_test_called():
2121
"""
2222
)
2323

24-
result = testdir.runpytest()
24+
result = testdir.runpytest("-s")
2525

2626
result.assert_outcomes(passed=2)
2727

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import pytest
2+
from pytest_trio import trio_fixture
3+
4+
import contextvars
5+
6+
cv = contextvars.ContextVar("cv", default=None)
7+
8+
9+
@trio_fixture
10+
def cv_checker():
11+
assert cv.get() is None
12+
yield
13+
assert cv.get() is None
14+
15+
16+
@trio_fixture
17+
def cv_setter(cv_checker):
18+
assert cv.get() is None
19+
token = cv.set("cv_setter")
20+
yield
21+
assert cv.get() == "cv_setter2"
22+
cv.reset(token)
23+
assert cv.get() is None
24+
25+
26+
@trio_fixture
27+
def cv_setter2(cv_setter):
28+
assert cv.get() == "cv_setter"
29+
# Intentionally leak, so can check that this is visible back in cv_setter
30+
cv.set("cv_setter2")
31+
yield
32+
assert cv.get() == "cv_setter2"
33+
34+
35+
@pytest.mark.trio
36+
async def test_contextvars(cv_setter2):
37+
assert cv.get() == "cv_setter2"
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import pytest
2+
from pytest_trio import trio_fixture
3+
4+
from .helpers import enable_trio_mode
5+
6+
7+
def test_trio_fixture_with_non_trio_test(testdir):
8+
testdir.makepyfile(
9+
"""
10+
import trio
11+
from pytest_trio import trio_fixture
12+
import pytest
13+
14+
@trio_fixture
15+
def trio_time():
16+
return trio.current_time()
17+
18+
@pytest.fixture
19+
def indirect_trio_time(trio_time):
20+
return trio_time + 1
21+
22+
@pytest.mark.trio
23+
async def test_async(mock_clock, trio_time, indirect_trio_time):
24+
assert trio_time == 0
25+
assert indirect_trio_time == 1
26+
27+
def test_sync(trio_time):
28+
pass
29+
30+
def test_sync_indirect(indirect_trio_time):
31+
pass
32+
"""
33+
)
34+
35+
result = testdir.runpytest()
36+
37+
result.assert_outcomes(passed=1, error=2)
38+
result.stdout.fnmatch_lines(
39+
["*: Trio fixtures can only be used by Trio tests*"]
40+
)
41+
42+
43+
def test_trio_fixture_with_wrong_scope_without_trio_mode(testdir):
44+
# There's a trick here: when you have a non-function-scope fixture, it's
45+
# not instantiated for any particular function (obviously). So... when our
46+
# pytest_fixture_setup hook tries to check for marks, it can't normally
47+
# see @pytest.mark.trio. So... it's actually almost impossible to have an
48+
# async fixture get treated as a Trio fixture *and* have it be
49+
# non-function-scope. But, class-scoped fixtures can see marks on the
50+
# class, so this is one way (the only way?) it can happen:
51+
testdir.makepyfile(
52+
"""
53+
import pytest
54+
55+
@pytest.fixture(scope="class")
56+
async def async_class_fixture():
57+
pass
58+
59+
@pytest.mark.trio
60+
class TestFoo:
61+
async def test_foo(self, async_class_fixture):
62+
pass
63+
"""
64+
)
65+
66+
result = testdir.runpytest()
67+
68+
result.assert_outcomes(error=1)
69+
result.stdout.fnmatch_lines(["*: Trio fixtures must be function-scope*"])
70+
71+
72+
@enable_trio_mode
73+
def test_trio_fixture_with_wrong_scope_in_trio_mode(testdir, enable_trio_mode):
74+
enable_trio_mode(testdir)
75+
76+
testdir.makepyfile(
77+
"""
78+
import pytest
79+
80+
@pytest.fixture(scope="session")
81+
async def async_session_fixture():
82+
pass
83+
84+
85+
async def test_whatever(async_session_fixture):
86+
pass
87+
"""
88+
)
89+
90+
result = testdir.runpytest()
91+
92+
result.assert_outcomes(error=1)
93+
result.stdout.fnmatch_lines(["*: Trio fixtures must be function-scope*"])
94+
95+
96+
@enable_trio_mode
97+
def test_async_fixture_with_sync_test_in_trio_mode(testdir, enable_trio_mode):
98+
enable_trio_mode(testdir)
99+
100+
testdir.makepyfile(
101+
"""
102+
import pytest
103+
104+
@pytest.fixture
105+
async def async_fixture():
106+
pass
107+
108+
109+
def test_whatever(async_fixture):
110+
pass
111+
"""
112+
)
113+
114+
result = testdir.runpytest()
115+
116+
result.assert_outcomes(error=1)
117+
result.stdout.fnmatch_lines(
118+
["*: Trio fixtures can only be used by Trio tests*"]
119+
)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import pytest
2+
from pytest_trio import trio_fixture
3+
import trio
4+
5+
6+
@trio_fixture
7+
def fixture_with_unique_name(nursery):
8+
nursery.start_soon(trio.sleep_forever)
9+
10+
11+
@pytest.mark.trio
12+
async def test_fixture_names(fixture_with_unique_name):
13+
# This might be a bit fragile ... if we rearrange the nursery hierarchy
14+
# somehow so it breaks, then we can make it more robust.
15+
task = trio.hazmat.current_task()
16+
assert task.name == "<test 'test_fixture_names'>"
17+
sibling_names = {task.name for task in task.parent_nursery.child_tasks}
18+
assert "<fixture 'fixture_with_unique_name'>" in sibling_names
File renamed without changes.

0 commit comments

Comments
 (0)