File tree 4 files changed +40
-1
lines changed
4 files changed +40
-1
lines changed Original file line number Diff line number Diff line change
1
+ RELEASE_TYPE: minor
2
+
3
+ Our pytest plugin now warns you when strategy functions have been collected
4
+ as tests, which may happen when e.g. using the
5
+ :func: `@composite <hypothesis.strategies.composite> ` decorator when you
6
+ should be using ``@given(st.data()) `` for inline draws.
7
+ Such functions *always * pass when treated as tests, because the lazy creation
8
+ of strategies mean that the function body is never actually executed!
Original file line number Diff line number Diff line change 22
22
import pytest
23
23
24
24
from hypothesis import Verbosity , core , settings
25
+ from hypothesis ._settings import note_deprecation
25
26
from hypothesis .reporting import default as default_reporter
26
27
from hypothesis .reporting import with_reporter
27
28
from hypothesis .statistics import collector
@@ -183,8 +184,19 @@ def pytest_collection_modifyitems(items):
183
184
for item in items :
184
185
if not isinstance (item , pytest .Function ):
185
186
continue
186
- if getattr (item .function , 'is_hypothesis_test' , False ):
187
+ if is_hypothesis_test (item .obj ):
187
188
item .add_marker ('hypothesis' )
189
+ if getattr (item .obj , 'is_hypothesis_strategy_function' , False ):
190
+ def note_strategy_is_not_test (* args , ** kwargs ):
191
+ note_deprecation (
192
+ '%s is a function that returns a Hypothesis strategy, '
193
+ 'but pytest has collected it as a test function. This '
194
+ 'is useless as the function body will never be executed.'
195
+ 'To define a test function, use @given instead of '
196
+ '@composite.' % (item .nodeid ,)
197
+ )
198
+
199
+ item .obj = note_strategy_is_not_test
188
200
189
201
190
202
def load ():
Original file line number Diff line number Diff line change @@ -196,6 +196,8 @@ def accept(*args, **kwargs):
196
196
result .force_has_reusable_values = True
197
197
assert result .has_reusable_values
198
198
return result
199
+
200
+ accept .is_hypothesis_strategy_function = True
199
201
return accept
200
202
return decorator
201
203
Original file line number Diff line number Diff line change @@ -152,3 +152,20 @@ def test_healthcheck_traceback_is_hidden(testdir):
152
152
def_line = get_line_num (def_token , result )
153
153
timeout_line = get_line_num (timeout_token , result )
154
154
assert timeout_line - def_line == 6
155
+
156
+
157
+ COMPOSITE_IS_NOT_A_TEST = """
158
+ from hypothesis.strategies import composite
159
+ @composite
160
+ def test_data_factory(draw):
161
+ assert False, 'Unreachable due to lazy construction'
162
+ """
163
+
164
+
165
+ @pytest .mark .skipif (pytest .__version__ [:3 ] == '3.0' , reason = 'very very old' )
166
+ def test_deprecation_of_strategies_as_tests (testdir ):
167
+ script = testdir .makepyfile (COMPOSITE_IS_NOT_A_TEST )
168
+ testdir .runpytest (script , '-Werror' ).assert_outcomes (failed = 1 )
169
+ result = testdir .runpytest (script )
170
+ result .assert_outcomes (passed = 1 )
171
+ result .stdout .fnmatch_lines (['*HypothesisDeprecationWarning*' ])
You can’t perform that action at this time.
0 commit comments