Skip to content

Commit

Permalink
Support Trio testing with Hypothesis
Browse files Browse the repository at this point in the history
  • Loading branch information
Zac-HD committed Jun 29, 2018
1 parent 8a52d49 commit ccd5ec2
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ htmlcov/
.cache
nosetests.xml
coverage.xml
.hypothesis/
.pytest_cache/

# Translations
*.mo
Expand Down
2 changes: 2 additions & 0 deletions newsfragments/42.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pytest-trio now integrates with `Hypothesis <https://hypothesis.readthedocs.io>`_
to support ``@given`` on async tests using Trio.
22 changes: 22 additions & 0 deletions pytest_trio/_tests/test_hypothesis_interaction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import pytest
from hypothesis import given, strategies as st


@given(st.integers())
@pytest.mark.trio
async def test_mark_inner(n):
assert isinstance(n, int)


@pytest.mark.trio
@given(st.integers())
async def test_mark_outer(n):
assert isinstance(n, int)


@pytest.mark.parametrize('y', [1, 2])
@given(x=st.none())
@pytest.mark.trio
async def test_mark_and_parametrize(x, y):
assert x is None
assert y in (1, 2)
28 changes: 23 additions & 5 deletions pytest_trio/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,18 @@ def pytest_configure(config):
)


def _trio_test_runner_factory(item):
testfunc = item.function
def _trio_test_runner_factory(item, testfunc=None):
testfunc = testfunc or item.function

if getattr(testfunc, '_trio_test_runner_wrapped', False):
# We have already wrapped this, perhaps because we combined Hypothesis
# with pytest.mark.parametrize
return testfunc

if not iscoroutinefunction(testfunc):
pytest.fail(
'test function `%r` is marked trio but is not async' % item
)

@trio_test
async def _bootstrap_fixture_and_run_test(**kwargs):
Expand Down Expand Up @@ -58,6 +68,7 @@ async def _bootstrap_fixture_and_run_test(**kwargs):
if user_exc:
raise user_exc

_bootstrap_fixture_and_run_test._trio_test_runner_wrapped = True
return _bootstrap_fixture_and_run_test


Expand Down Expand Up @@ -215,11 +226,18 @@ def _install_async_fixture_if_needed(fixturedef, request):
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_call(item):
if 'trio' in item.keywords:
if not iscoroutinefunction(item.obj):
if hasattr(item.obj, 'hypothesis'):
# If it's a Hypothesis test, we go in a layer.
item.obj.hypothesis.inner_test = _trio_test_runner_factory(
item, item.obj.hypothesis.inner_test
)
elif getattr(item.obj, 'is_hypothesis_test', False):
pytest.fail(
'test function `%r` is marked trio but is not async' % item
'test function `%r` is using Hypothesis, but pytest-trio '
'only works with Hypothesis 3.64.0 or later.' % item
)
item.obj = _trio_test_runner_factory(item)
else:
item.obj = _trio_test_runner_factory(item)

yield

Expand Down
1 change: 1 addition & 0 deletions test-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pytest
pytest-cov
hypothesis>=3.64

0 comments on commit ccd5ec2

Please sign in to comment.