From 616b2f36d528ce7d6a34b7f1c72b42386584c36c Mon Sep 17 00:00:00 2001 From: Zac-HD Date: Fri, 26 Nov 2021 12:42:15 +1100 Subject: [PATCH] Improve fixture message This isn't perfect, but it seems like a big improvement over the status quo. Closes #3018. Co-Authored-By: Stuart Cook --- .../src/_hypothesis_pytestplugin.py | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/hypothesis-python/src/_hypothesis_pytestplugin.py b/hypothesis-python/src/_hypothesis_pytestplugin.py index 1bf16596e1..27085bdf3d 100644 --- a/hypothesis-python/src/_hypothesis_pytestplugin.py +++ b/hypothesis-python/src/_hypothesis_pytestplugin.py @@ -44,6 +44,19 @@ SEED_OPTION, EXPLAIN_OPTION, ] +_FIXTURE_MSG = """Function-scoped fixture {0!r} used by {1!r} + +Function-scoped fixtures are not reset between examples generated by +`@given(...)`, which is often surprising and can cause subtle test bugs. + +If you were expecting the fixture to run separately for each generated example, +then unfortunately you will need to find a different way to achieve your goal +(e.g. using a similar context manager instead of a fixture). + +If you are confident that your test will work correctly even though the +fixture is not reset between generated examples, you can suppress this health +check to assure Hypothesis that you understand what you are doing. +""" class StoringReporter: @@ -222,15 +235,6 @@ def pytest_runtest_call(item): # Warn about function-scoped fixtures, excluding autouse fixtures because # the advice is probably not actionable and the status quo seems OK... # See https://github.com/HypothesisWorks/hypothesis/issues/377 for detail. - msg = ( - "%s uses the %r fixture, which is reset between function calls but not " - "between test cases generated by `@given(...)`. You can change it to " - "a module- or session-scoped fixture if it is safe to reuse; if not " - "we recommend using a context manager inside your test function. See " - "https://docs.pytest.org/en/latest/how-to/fixtures.html" - "#scope-sharing-fixtures-across-classes-modules-packages-or-session " - "for details on fixture scope." - ) argnames = None for fx_defs in item._request._fixturemanager.getfixtureinfo( node=item, func=item.function, cls=None @@ -243,7 +247,7 @@ def pytest_runtest_call(item): if active_fx.scope == "function": fail_health_check( settings, - msg % (item.nodeid, fx.argname), + _FIXTURE_MSG.format(fx.argname, item.nodeid), HealthCheck.function_scoped_fixture, )