@@ -25,8 +25,18 @@ def pytest_configure(config):
2525 )
2626
2727
28- def _trio_test_runner_factory (item ):
29- testfunc = item .function
28+ def _trio_test_runner_factory (item , testfunc = None ):
29+ testfunc = testfunc or item .function
30+
31+ if getattr (testfunc , '_trio_test_runner_wrapped' , False ):
32+ # We have already wrapped this, perhaps because we combined Hypothesis
33+ # with pytest.mark.parametrize
34+ return testfunc
35+
36+ if not iscoroutinefunction (testfunc ):
37+ pytest .fail (
38+ 'test function `%r` is marked trio but is not async' % item
39+ )
3040
3141 @trio_test
3242 async def _bootstrap_fixture_and_run_test (** kwargs ):
@@ -58,6 +68,7 @@ async def _bootstrap_fixture_and_run_test(**kwargs):
5868 if user_exc :
5969 raise user_exc
6070
71+ _bootstrap_fixture_and_run_test ._trio_test_runner_wrapped = True
6172 return _bootstrap_fixture_and_run_test
6273
6374
@@ -215,11 +226,18 @@ def _install_async_fixture_if_needed(fixturedef, request):
215226@pytest .hookimpl (hookwrapper = True )
216227def pytest_runtest_call (item ):
217228 if 'trio' in item .keywords :
218- if not iscoroutinefunction (item .obj ):
229+ if hasattr (item .obj , 'hypothesis' ):
230+ # If it's a Hypothesis test, we go in a layer.
231+ item .obj .hypothesis .inner_test = _trio_test_runner_factory (
232+ item , item .obj .hypothesis .inner_test
233+ )
234+ elif getattr (item .obj , 'is_hypothesis_test' , False ):
219235 pytest .fail (
220- 'test function `%r` is marked trio but is not async' % item
236+ 'test function `%r` is using Hypothesis, but pytest-trio '
237+ 'only works with Hypothesis 3.64.0 or later.' % item
221238 )
222- item .obj = _trio_test_runner_factory (item )
239+ else :
240+ item .obj = _trio_test_runner_factory (item )
223241
224242 yield
225243
0 commit comments