-
-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #50 from njsmith/fixture-rework
Rework fixtures
- Loading branch information
Showing
17 changed files
with
892 additions
and
214 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
"""Top-level package for pytest-trio.""" | ||
|
||
from ._version import __version__ | ||
from .plugin import trio_fixture | ||
|
||
__all__ = ["trio_fixture"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import pytest | ||
|
||
|
||
def enable_trio_mode_via_pytest_ini(testdir): | ||
testdir.makefile(".ini", pytest="[pytest]\ntrio_mode = true\n") | ||
|
||
|
||
def enable_trio_mode_via_conftest_py(testdir): | ||
testdir.makeconftest("from pytest_trio.enable_trio_mode import *") | ||
|
||
|
||
enable_trio_mode = pytest.mark.parametrize( | ||
"enable_trio_mode", | ||
[enable_trio_mode_via_pytest_ini, enable_trio_mode_via_conftest_py] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import pytest | ||
from pytest_trio import trio_fixture | ||
|
||
import contextvars | ||
|
||
cv = contextvars.ContextVar("cv", default=None) | ||
|
||
|
||
@trio_fixture | ||
def cv_checker(): | ||
assert cv.get() is None | ||
yield | ||
assert cv.get() is None | ||
|
||
|
||
@trio_fixture | ||
def cv_setter(cv_checker): | ||
assert cv.get() is None | ||
token = cv.set("cv_setter") | ||
yield | ||
assert cv.get() == "cv_setter2" | ||
cv.reset(token) | ||
assert cv.get() is None | ||
|
||
|
||
@trio_fixture | ||
def cv_setter2(cv_setter): | ||
assert cv.get() == "cv_setter" | ||
# Intentionally leak, so can check that this is visible back in cv_setter | ||
cv.set("cv_setter2") | ||
yield | ||
assert cv.get() == "cv_setter2" | ||
|
||
|
||
@pytest.mark.trio | ||
async def test_contextvars(cv_setter2): | ||
assert cv.get() == "cv_setter2" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import pytest | ||
from pytest_trio import trio_fixture | ||
|
||
from .helpers import enable_trio_mode | ||
|
||
|
||
def test_trio_fixture_with_non_trio_test(testdir): | ||
testdir.makepyfile( | ||
""" | ||
import trio | ||
from pytest_trio import trio_fixture | ||
import pytest | ||
@trio_fixture | ||
def trio_time(): | ||
return trio.current_time() | ||
@pytest.fixture | ||
def indirect_trio_time(trio_time): | ||
return trio_time + 1 | ||
@pytest.mark.trio | ||
async def test_async(mock_clock, trio_time, indirect_trio_time): | ||
assert trio_time == 0 | ||
assert indirect_trio_time == 1 | ||
def test_sync(trio_time): | ||
pass | ||
def test_sync_indirect(indirect_trio_time): | ||
pass | ||
""" | ||
) | ||
|
||
result = testdir.runpytest() | ||
|
||
result.assert_outcomes(passed=1, error=2) | ||
result.stdout.fnmatch_lines( | ||
["*: Trio fixtures can only be used by Trio tests*"] | ||
) | ||
|
||
|
||
def test_trio_fixture_with_wrong_scope_without_trio_mode(testdir): | ||
# There's a trick here: when you have a non-function-scope fixture, it's | ||
# not instantiated for any particular function (obviously). So... when our | ||
# pytest_fixture_setup hook tries to check for marks, it can't normally | ||
# see @pytest.mark.trio. So... it's actually almost impossible to have an | ||
# async fixture get treated as a Trio fixture *and* have it be | ||
# non-function-scope. But, class-scoped fixtures can see marks on the | ||
# class, so this is one way (the only way?) it can happen: | ||
testdir.makepyfile( | ||
""" | ||
import pytest | ||
@pytest.fixture(scope="class") | ||
async def async_class_fixture(): | ||
pass | ||
@pytest.mark.trio | ||
class TestFoo: | ||
async def test_foo(self, async_class_fixture): | ||
pass | ||
""" | ||
) | ||
|
||
result = testdir.runpytest() | ||
|
||
result.assert_outcomes(error=1) | ||
result.stdout.fnmatch_lines(["*: Trio fixtures must be function-scope*"]) | ||
|
||
|
||
@enable_trio_mode | ||
def test_trio_fixture_with_wrong_scope_in_trio_mode(testdir, enable_trio_mode): | ||
enable_trio_mode(testdir) | ||
|
||
testdir.makepyfile( | ||
""" | ||
import pytest | ||
@pytest.fixture(scope="session") | ||
async def async_session_fixture(): | ||
pass | ||
async def test_whatever(async_session_fixture): | ||
pass | ||
""" | ||
) | ||
|
||
result = testdir.runpytest() | ||
|
||
result.assert_outcomes(error=1) | ||
result.stdout.fnmatch_lines(["*: Trio fixtures must be function-scope*"]) | ||
|
||
|
||
@enable_trio_mode | ||
def test_async_fixture_with_sync_test_in_trio_mode(testdir, enable_trio_mode): | ||
enable_trio_mode(testdir) | ||
|
||
testdir.makepyfile( | ||
""" | ||
import pytest | ||
@pytest.fixture | ||
async def async_fixture(): | ||
pass | ||
def test_whatever(async_fixture): | ||
pass | ||
""" | ||
) | ||
|
||
result = testdir.runpytest() | ||
|
||
result.assert_outcomes(error=1) | ||
result.stdout.fnmatch_lines( | ||
["*: Trio fixtures can only be used by Trio tests*"] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import pytest | ||
from pytest_trio import trio_fixture | ||
import trio | ||
|
||
|
||
@trio_fixture | ||
def fixture_with_unique_name(nursery): | ||
nursery.start_soon(trio.sleep_forever) | ||
|
||
|
||
@pytest.mark.trio | ||
async def test_fixture_names(fixture_with_unique_name): | ||
# This might be a bit fragile ... if we rearrange the nursery hierarchy | ||
# somehow so it breaks, then we can make it more robust. | ||
task = trio.hazmat.current_task() | ||
assert task.name == "<test 'test_fixture_names'>" | ||
sibling_names = {task.name for task in task.parent_nursery.child_tasks} | ||
assert "<fixture 'fixture_with_unique_name'>" in sibling_names |
File renamed without changes.
Oops, something went wrong.