Skip to content

Commit 3e8e8b3

Browse files
authored
Merge pull request #4090 from Zac-HD/test-cleanups
Various test cleanups for Crosshair integration
2 parents c90732c + ae1a2d0 commit 3e8e8b3

17 files changed

+55
-85
lines changed

hypothesis-python/RELEASE.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
RELEASE_TYPE: patch
2+
3+
This patch contains some internal code cleanup. There is no user-visible change.

hypothesis-python/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def local_file(name):
6060
"pytest": ["pytest>=4.6"],
6161
"dpcontracts": ["dpcontracts>=0.4"],
6262
"redis": ["redis>=3.0.0"],
63-
"crosshair": ["hypothesis-crosshair>=0.0.13", "crosshair-tool>=0.0.68"],
63+
"crosshair": ["hypothesis-crosshair>=0.0.13", "crosshair-tool>=0.0.70"],
6464
# zoneinfo is an odd one: every dependency is conditional, because they're
6565
# only necessary on old versions of Python or Windows systems or emscripten.
6666
"zoneinfo": [

hypothesis-python/src/hypothesis/internal/conjecture/data.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1935,14 +1935,6 @@ def permitted(f):
19351935
}
19361936

19371937

1938-
# eventually we'll want to expose this publicly, but for now it lives as psuedo-internal.
1939-
def realize(value: object) -> object:
1940-
from hypothesis.control import current_build_context
1941-
1942-
context = current_build_context()
1943-
return context.data.provider.realize(value)
1944-
1945-
19461938
class ConjectureData:
19471939
@classmethod
19481940
def for_buffer(

hypothesis-python/src/hypothesis/internal/conjecture/engine.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1112,7 +1112,7 @@ def generate_mutations_from(
11121112
(start1, end1), (start2, end2) = self.random.sample(sorted(group), 2)
11131113
if (start1 <= start2 <= end2 <= end1) or (
11141114
start2 <= start1 <= end1 <= end2
1115-
):
1115+
): # pragma: no cover # flaky on conjecture-cover tests
11161116
# one example entirely contains the other. give up.
11171117
# TODO use more intelligent mutation for containment, like
11181118
# replacing child with parent or vice versa. Would allow for

hypothesis-python/tests/array_api/test_arrays.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,7 @@ def test_minimize_large_uint_arrays(xp, xps):
187187
example."""
188188
if not hasattr(xp, "nonzero"):
189189
pytest.skip("optional API")
190-
smallest = minimal(
191-
xps.arrays(xp.uint8, 100),
192-
lambda x: xp.any(x) and not xp.all(x),
193-
timeout_after=60,
194-
)
190+
smallest = minimal(xps.arrays(xp.uint8, 100), lambda x: xp.any(x) and not xp.all(x))
195191
assert xp.all(xp.logical_or(smallest == 0, smallest == 1))
196192
idx = xp.nonzero(smallest)[0]
197193
assert idx.size in (1, smallest.size - 1)

hypothesis-python/tests/common/debug.py

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,21 @@ class Timeout(BaseException):
2525
pass
2626

2727

28-
def minimal(definition, condition=lambda x: True, settings=None, timeout_after=10):
28+
def minimal(definition, condition=lambda x: True, settings=None):
2929
definition.validate()
30-
runtime = None
3130
result = None
3231

32+
def wrapped_condition(x):
33+
# This sure seems pointless, but `test_sum_of_pair` fails otherwise...
34+
return condition(x)
35+
3336
if (
3437
context := _current_build_context.value
3538
) and context.data.provider.avoid_realization:
3639
raise SkipTest("`minimal()` helper not supported under symbolic execution")
3740

38-
def wrapped_condition(x):
39-
nonlocal runtime
40-
if timeout_after is not None:
41-
if runtime:
42-
runtime += TIME_INCREMENT
43-
if runtime >= timeout_after:
44-
raise Timeout
45-
result = condition(x)
46-
if result and not runtime:
47-
runtime = 0.0
48-
return result
49-
5041
if settings is None:
51-
settings = Settings(max_examples=50000, phases=(Phase.generate, Phase.shrink))
42+
settings = Settings(max_examples=500, phases=(Phase.generate, Phase.shrink))
5243

5344
verbosity = settings.verbosity
5445
if verbosity == Verbosity.normal:

hypothesis-python/tests/conjecture/test_alt_backend.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
import pytest
1919

2020
from hypothesis import given, settings, strategies as st
21+
from hypothesis.control import current_build_context
2122
from hypothesis.database import InMemoryExampleDatabase
2223
from hypothesis.errors import Flaky, HypothesisException, InvalidArgument
2324
from hypothesis.internal.compat import int_to_bytes
2425
from hypothesis.internal.conjecture.data import (
2526
AVAILABLE_PROVIDERS,
2627
ConjectureData,
2728
PrimitiveProvider,
28-
realize,
2929
)
3030
from hypothesis.internal.conjecture.engine import ConjectureRunner
3131
from hypothesis.internal.floats import SIGNALING_NAN
@@ -412,7 +412,7 @@ def test_realize():
412412
@given(st.integers())
413413
@settings(backend="realize")
414414
def test_function(n):
415-
values.append(realize(n))
415+
values.append(current_build_context().data.provider.realize(n))
416416

417417
test_function()
418418

hypothesis-python/tests/cover/test_core.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,20 @@ def inner(x):
8080

8181

8282
def test_pytest_skip_skips_shrinking():
83-
values = []
83+
seen_large = False
8484

8585
@settings(derandomize=True, max_examples=100)
8686
@given(s.integers())
8787
def inner(x):
88-
values.append(x)
88+
nonlocal seen_large
8989
if x > 100:
90+
if seen_large:
91+
raise Exception("Should never replay a skipped test!")
92+
seen_large = True
9093
pytest.skip(f"{x=} is too big!")
9194

9295
with pytest.raises(Skipped):
9396
inner()
94-
assert len([x for x in values if x > 100]) == 1
9597

9698

9799
def test_can_find_with_db_eq_none():

hypothesis-python/tests/cover/test_datetimes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def test_bordering_on_a_leap_year():
7373
dt.datetime.min.replace(year=2003), dt.datetime.max.replace(year=2005)
7474
),
7575
lambda x: x.month == 2 and x.day == 29,
76-
timeout_after=60,
76+
settings=settings(max_examples=1200),
7777
)
7878
assert x.year == 2004
7979

hypothesis-python/tests/cover/test_deadline.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def test_slow_with_none_deadline(i):
5353
def test_raises_flaky_if_a_test_becomes_fast_on_rerun():
5454
once = [True]
5555

56-
@settings(deadline=500)
56+
@settings(deadline=500, backend="hypothesis")
5757
@given(st.integers())
5858
def test_flaky_slow(i):
5959
if once[0]:
@@ -82,11 +82,10 @@ def test_keeps_you_well_above_the_deadline():
8282
seen = set()
8383
failed_once = [False]
8484

85-
@settings(deadline=100)
85+
@settings(deadline=100, backend="hypothesis")
8686
@given(st.integers(0, 2000))
8787
def slow(i):
88-
# Make sure our initial failure isn't something that immediately goes
89-
# flaky.
88+
# Make sure our initial failure isn't something that immediately goes flaky.
9089
if not failed_once[0]:
9190
if i * 0.9 <= 100:
9291
return
@@ -107,7 +106,7 @@ def slow(i):
107106
def test_gives_a_deadline_specific_flaky_error_message():
108107
once = [True]
109108

110-
@settings(deadline=100)
109+
@settings(deadline=100, backend="hypothesis")
111110
@given(st.integers())
112111
def slow_once(i):
113112
if once[0]:

hypothesis-python/tests/cover/test_health_checks.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
99
# obtain one at https://mozilla.org/MPL/2.0/.
1010

11+
import re
1112
import time
1213

1314
import pytest
14-
from pytest import raises
1515

1616
from hypothesis import HealthCheck, given, settings, strategies as st
17-
from hypothesis.control import assume
17+
from hypothesis.control import assume, current_build_context
1818
from hypothesis.errors import FailedHealthCheck, InvalidArgument
1919
from hypothesis.internal.compat import int_from_bytes
2020
from hypothesis.stateful import (
@@ -28,26 +28,28 @@
2828

2929
from tests.common.utils import no_shrink
3030

31-
HEALTH_CHECK_SETTINGS = settings(max_examples=11, database=None)
31+
HEALTH_CHECK_SETTINGS = settings(
32+
max_examples=11, database=None, suppress_health_check=()
33+
)
3234

3335

3436
def test_slow_generation_fails_a_health_check():
35-
@HEALTH_CHECK_SETTINGS
37+
@settings(HEALTH_CHECK_SETTINGS, deadline=200)
3638
@given(st.integers().map(lambda x: time.sleep(0.2)))
3739
def test(x):
3840
pass
3941

40-
with raises(FailedHealthCheck):
42+
with pytest.raises(FailedHealthCheck):
4143
test()
4244

4345

4446
def test_slow_generation_inline_fails_a_health_check():
45-
@HEALTH_CHECK_SETTINGS
47+
@settings(HEALTH_CHECK_SETTINGS, deadline=200)
4648
@given(st.data())
4749
def test(data):
4850
data.draw(st.integers().map(lambda x: time.sleep(0.2)))
4951

50-
with raises(FailedHealthCheck):
52+
with pytest.raises(FailedHealthCheck):
5153
test()
5254

5355

@@ -75,7 +77,7 @@ def unhealthy_filter(x):
7577
def test1(x):
7678
raise ValueError
7779

78-
with raises(FailedHealthCheck):
80+
with pytest.raises(FailedHealthCheck):
7981
test1()
8082

8183
forbidden = set()
@@ -85,7 +87,7 @@ def test1(x):
8587
def test2(x):
8688
raise ValueError
8789

88-
with raises(ValueError):
90+
with pytest.raises(ValueError):
8991
test2()
9092

9193

@@ -95,9 +97,8 @@ def test_filtering_everything_fails_a_health_check():
9597
def test(x):
9698
pass
9799

98-
with raises(FailedHealthCheck) as e:
100+
with pytest.raises(FailedHealthCheck, match="filter"):
99101
test()
100-
assert "filter" in e.value.args[0]
101102

102103

103104
class fails_regularly(SearchStrategy):
@@ -109,21 +110,21 @@ def do_draw(self, data):
109110

110111
def test_filtering_most_things_fails_a_health_check():
111112
@given(fails_regularly())
112-
@settings(database=None, phases=no_shrink)
113+
@settings(database=None, phases=no_shrink, suppress_health_check=())
113114
def test(x):
114-
pass
115+
if current_build_context().data.provider.avoid_realization:
116+
pytest.skip("symbolic backends can filter efficiently!")
115117

116-
with raises(FailedHealthCheck) as e:
118+
with pytest.raises(FailedHealthCheck, match="filter"):
117119
test()
118-
assert "filter" in e.value.args[0]
119120

120121

121122
def test_returning_non_none_is_forbidden():
122123
@given(st.integers())
123124
def a(x):
124125
return 1
125126

126-
with raises(FailedHealthCheck):
127+
with pytest.raises(FailedHealthCheck):
127128
a()
128129

129130

@@ -153,19 +154,18 @@ def test(self, _):
153154

154155
def test_differing_executors_fails_health_check():
155156
sample_test_runner().test()
156-
with pytest.raises(FailedHealthCheck) as exc:
157+
msg = re.escape(str(HealthCheck.differing_executors))
158+
with pytest.raises(FailedHealthCheck, match=msg):
157159
sample_test_runner().test()
158160

159-
assert str(HealthCheck.differing_executors) in str(exc.value)
160-
161161

162162
def test_it_is_an_error_to_suppress_non_iterables():
163-
with raises(InvalidArgument):
163+
with pytest.raises(InvalidArgument):
164164
settings(suppress_health_check=1)
165165

166166

167167
def test_it_is_an_error_to_suppress_non_healthchecks():
168-
with raises(InvalidArgument):
168+
with pytest.raises(InvalidArgument):
169169
settings(suppress_health_check=[1])
170170

171171

hypothesis-python/tests/cover/test_targeting.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import pytest
1414

1515
from hypothesis import example, given, strategies as st, target
16+
from hypothesis.control import current_build_context
1617
from hypothesis.errors import InvalidArgument
1718

1819

@@ -92,6 +93,8 @@ def test_cannot_target_outside_test():
9293

9394
@given(st.none())
9495
def test_cannot_target_same_label_twice(_):
96+
if current_build_context().data.provider.avoid_realization:
97+
pytest.skip("target() is a noop to avoid realizing arguments")
9598
target(0.0, label="label")
9699
with pytest.raises(InvalidArgument):
97100
target(1.0, label="label")

hypothesis-python/tests/nocover/test_randomization.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
99
# obtain one at https://mozilla.org/MPL/2.0/.
1010

11-
from pytest import raises
11+
import pytest
1212

1313
from hypothesis import Verbosity, core, find, given, settings, strategies as st
1414

@@ -35,7 +35,7 @@ def test_blah(x, rnd):
3535
def test_nest(y):
3636
assert y < x
3737

38-
with raises(AssertionError):
38+
with pytest.raises(AssertionError):
3939
test_nest()
4040

4141
test_blah()

hypothesis-python/tests/nocover/test_recursive.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ def flatten(x):
3434
max_leaves=size * 2,
3535
),
3636
lambda x: isinstance(x, list) and len(flatten(x)) >= size,
37-
timeout_after=None,
3837
)
3938
assert flatten(xs) == [0] * size
4039

@@ -46,11 +45,7 @@ def depth(x):
4645
else:
4746
return 1
4847

49-
xs = minimal(
50-
st.recursive(st.integers(), st.lists),
51-
lambda x: depth(x) > 1,
52-
timeout_after=None,
53-
)
48+
xs = minimal(st.recursive(st.integers(), st.lists), lambda x: depth(x) > 1)
5449
assert xs in ([0], [[]])
5550

5651

@@ -67,7 +62,6 @@ def breadth(x):
6762
st.recursive(st.booleans(), lambda x: st.lists(x, max_size=target // 2)),
6863
lambda x: breadth(x) >= target,
6964
settings=settings(max_examples=10000),
70-
timeout_after=None,
7165
)
7266
assert breadth(broad) == target
7367

@@ -79,7 +73,7 @@ def test_drawing_many_near_boundary():
7973
lambda x: st.lists(x, min_size=2 * (size - 1), max_size=2 * size).map(tuple),
8074
max_leaves=2 * size - 1,
8175
)
82-
ls = minimal(st.lists(elems), lambda x: len(set(x)) >= size, timeout_after=None)
76+
ls = minimal(st.lists(elems), lambda x: len(set(x)) >= size)
8377
assert len(ls) == size
8478

8579

@@ -117,7 +111,7 @@ def test_can_form_sets_of_recursive_data():
117111
max_leaves=20,
118112
)
119113
)
120-
xs = minimal(trees, lambda x: len(x) >= size, timeout_after=None)
114+
xs = minimal(trees, lambda x: len(x) >= size)
121115
assert len(xs) == size
122116

123117

0 commit comments

Comments
 (0)