Skip to content

Commit f5fcec9

Browse files
Евгений БлиновЕвгений Блинов
authored andcommitted
Add tests for BenchmarkResult serialization, percentile handling, and
ScenarioGroup addition behavior
1 parent a61b1e1 commit f5fcec9

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

tests/units/test_benchmark_result.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,12 @@ def test_mean_computed_correctly(self) -> None:
4040
assert result.mean == expected
4141

4242
def test_mean_uses_fsum_precision(self) -> None:
43-
# floating point: sum of many small numbers may differ from fsum
44-
durations = tuple(0.1 for _ in range(10))
43+
# fsum handles cancellation correctly; plain sum loses precision:
44+
# sum([1e20, 1.0, -1e20]) == 0.0, fsum == 1.0
45+
durations = (1e20, 1.0, -1e20)
4546
result = make_result(durations)
46-
expected = math.fsum(durations) / len(durations)
47-
assert result.mean == expected
47+
assert result.mean == pytest.approx(1.0 / 3)
48+
assert result.mean != sum(durations) / len(durations)
4849

4950
def test_best_is_min(self) -> None:
5051
result = make_result((3.0, 1.0, 2.0))
@@ -114,6 +115,8 @@ def test_percentile_100_returns_all(self) -> None:
114115
result = make_result((1.0, 2.0, 3.0))
115116
trimmed = result.percentile(100)
116117
assert len(trimmed.durations) == 3
118+
assert trimmed.is_primary is False
119+
assert trimmed.durations == tuple(sorted(result.durations))
117120

118121
def test_percentile_small_number(self) -> None:
119122
result = make_result((1.0, 2.0, 3.0))
@@ -213,6 +216,9 @@ def test_to_json_valid_json(self) -> None:
213216
result = make_result((0.1, 0.2))
214217
data = json.loads(result.to_json())
215218
assert isinstance(data, dict)
219+
assert isinstance(data['durations'], list)
220+
assert isinstance(data['is_primary'], bool)
221+
assert 'scenario' in data
216222

217223
def test_to_json_contains_durations(self) -> None:
218224
result = make_result((0.1, 0.2, 0.3))
@@ -312,6 +318,18 @@ def test_from_json_is_primary_not_bool_raises(self) -> None:
312318
with pytest.raises(ValueError, match='is_primary'):
313319
BenchmarkResult.from_json(payload)
314320

321+
def test_from_json_is_primary_int_raises(self) -> None:
322+
# int 1 is not a bool even though bool is a subclass of int
323+
payload = json.dumps({'durations': [0.1], 'is_primary': 1})
324+
with pytest.raises(ValueError, match='is_primary'):
325+
BenchmarkResult.from_json(payload)
326+
327+
def test_percentile_single_element(self) -> None:
328+
result = make_result((5.0,))
329+
trimmed = result.percentile(50)
330+
assert trimmed.durations == (5.0,)
331+
assert trimmed.is_primary is False
332+
315333
def test_from_json_missing_is_primary_raises(self) -> None:
316334
payload = json.dumps({'durations': [0.1, 0.2]})
317335
with pytest.raises(ValueError, match='required fields'):

tests/units/test_scenario.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ def test_run_result_is_primary(self) -> None:
209209

210210
def test_run_args_incompatible_raises_type_error(self) -> None:
211211
s = Scenario(lambda: None, args=[1, 2], name='s', number=1)
212-
with pytest.raises(TypeError):
212+
with pytest.raises(TypeError, match='argument'):
213213
s.run()
214214

215215
def test_run_exception_mid_iteration(self) -> None:
@@ -249,6 +249,9 @@ def test_radd_group_scenario(self) -> None:
249249
s1 = Scenario(lambda: None, name='s1')
250250
s2 = Scenario(lambda: None, name='s2')
251251
g = ScenarioGroup(s1)
252-
# g + s2 is g.__add__(s2), but we also want s2.__radd__(g) to work
252+
# s2.__radd__(g) = ScenarioGroup(*g._scenarios, s2) = [s1, s2]
253253
group = s2.__radd__(g)
254254
assert isinstance(group, ScenarioGroup)
255+
results = group.run()
256+
assert results[0].scenario is s1
257+
assert results[1].scenario is s2

0 commit comments

Comments
 (0)