Skip to content

Commit 1aef2dd

Browse files
Евгений БлиновЕвгений Блинов
authored andcommitted
Typing tests
1 parent 62d8d36 commit 1aef2dd

3 files changed

Lines changed: 203 additions & 0 deletions

File tree

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
from __future__ import annotations
2+
3+
import json
4+
5+
import pytest
6+
7+
from microbenchmark import BenchmarkResult, Scenario
8+
9+
10+
def make_result() -> BenchmarkResult:
11+
return Scenario(lambda: None, name='s', number=10).run()
12+
13+
14+
class TestBenchmarkResultPositiveTypes:
15+
def test_percentile_returns_benchmark_result(self) -> None:
16+
result = make_result()
17+
trimmed = result.percentile(50)
18+
assert isinstance(trimmed, BenchmarkResult)
19+
20+
def test_p95_returns_benchmark_result(self) -> None:
21+
result = make_result()
22+
assert isinstance(result.p95, BenchmarkResult)
23+
24+
def test_p99_returns_benchmark_result(self) -> None:
25+
result = make_result()
26+
assert isinstance(result.p99, BenchmarkResult)
27+
28+
def test_to_json_returns_str(self) -> None:
29+
result = make_result()
30+
assert isinstance(result.to_json(), str)
31+
32+
def test_from_json_returns_benchmark_result(self) -> None:
33+
result = make_result()
34+
restored = BenchmarkResult.from_json(result.to_json())
35+
assert isinstance(restored, BenchmarkResult)
36+
37+
def test_mean_is_float(self) -> None:
38+
result = make_result()
39+
assert isinstance(result.mean, float)
40+
41+
def test_best_is_float(self) -> None:
42+
result = make_result()
43+
assert isinstance(result.best, float)
44+
45+
def test_worst_is_float(self) -> None:
46+
result = make_result()
47+
assert isinstance(result.worst, float)
48+
49+
def test_is_primary_is_bool(self) -> None:
50+
result = make_result()
51+
assert isinstance(result.is_primary, bool)
52+
53+
def test_durations_is_tuple(self) -> None:
54+
result = make_result()
55+
assert isinstance(result.durations, tuple)
56+
57+
58+
class TestBenchmarkResultNegativeTypes:
59+
def test_percentile_zero_raises(self) -> None:
60+
result = make_result()
61+
with pytest.raises(ValueError):
62+
result.percentile(0)
63+
64+
def test_percentile_negative_raises(self) -> None:
65+
result = make_result()
66+
with pytest.raises(ValueError):
67+
result.percentile(-1)
68+
69+
def test_percentile_above_100_raises(self) -> None:
70+
result = make_result()
71+
with pytest.raises(ValueError):
72+
result.percentile(101)
73+
74+
def test_from_json_invalid_raises(self) -> None:
75+
with pytest.raises(Exception):
76+
BenchmarkResult.from_json('{not valid}')
77+
78+
def test_from_json_empty_object_raises(self) -> None:
79+
with pytest.raises(Exception):
80+
BenchmarkResult.from_json('{}')
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from __future__ import annotations
2+
3+
from microbenchmark import BenchmarkResult, Scenario, ScenarioGroup
4+
5+
6+
class TestScenarioGroupPositiveTypes:
7+
def test_empty_construction(self) -> None:
8+
g = ScenarioGroup()
9+
assert isinstance(g, ScenarioGroup)
10+
11+
def test_single_scenario(self) -> None:
12+
s = Scenario(lambda: None, name='s')
13+
g = ScenarioGroup(s)
14+
assert isinstance(g, ScenarioGroup)
15+
16+
def test_multiple_scenarios(self) -> None:
17+
s1 = Scenario(lambda: None, name='s1')
18+
s2 = Scenario(lambda: None, name='s2')
19+
g = ScenarioGroup(s1, s2)
20+
assert isinstance(g, ScenarioGroup)
21+
22+
def test_run_returns_list(self) -> None:
23+
g = ScenarioGroup()
24+
result = g.run()
25+
assert isinstance(result, list)
26+
27+
def test_run_returns_list_of_benchmark_results(self) -> None:
28+
s = Scenario(lambda: None, name='s', number=1)
29+
g = ScenarioGroup(s)
30+
results = g.run()
31+
for r in results:
32+
assert isinstance(r, BenchmarkResult)
33+
34+
def test_add_scenario_returns_group(self) -> None:
35+
g = ScenarioGroup()
36+
s = Scenario(lambda: None, name='s')
37+
result = g + s
38+
assert isinstance(result, ScenarioGroup)
39+
40+
def test_add_group_returns_group(self) -> None:
41+
g1 = ScenarioGroup()
42+
g2 = ScenarioGroup()
43+
result = g1 + g2
44+
assert isinstance(result, ScenarioGroup)
45+
46+
47+
class TestScenarioGroupNegativeTypes:
48+
def test_add_int_returns_not_implemented(self) -> None:
49+
g = ScenarioGroup()
50+
result = g.__add__(42) # type: ignore[arg-type]
51+
assert result is NotImplemented
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from __future__ import annotations
2+
3+
import time
4+
5+
import pytest
6+
7+
from microbenchmark import BenchmarkResult, Scenario, ScenarioGroup
8+
9+
10+
# ---------------------------------------------------------------------------
11+
# Positive type checks (runtime — confirm valid usage works)
12+
# ---------------------------------------------------------------------------
13+
14+
class TestScenarioPositiveTypes:
15+
def test_callable_function(self) -> None:
16+
s = Scenario(lambda: None, name='s')
17+
assert isinstance(s, Scenario)
18+
19+
def test_args_none(self) -> None:
20+
s = Scenario(lambda: None, args=None, name='s')
21+
assert isinstance(s, Scenario)
22+
23+
def test_args_list(self) -> None:
24+
s = Scenario(sum, args=[[1, 2, 3]], name='s')
25+
assert isinstance(s, Scenario)
26+
27+
def test_number_int(self) -> None:
28+
s = Scenario(lambda: None, name='s', number=100)
29+
assert isinstance(s, Scenario)
30+
31+
def test_timer_callable(self) -> None:
32+
s = Scenario(lambda: None, name='s', timer=time.perf_counter)
33+
assert isinstance(s, Scenario)
34+
35+
def test_run_returns_benchmark_result(self) -> None:
36+
result = Scenario(lambda: None, name='s', number=1).run()
37+
assert isinstance(result, BenchmarkResult)
38+
39+
def test_run_with_warmup_returns_benchmark_result(self) -> None:
40+
result = Scenario(lambda: None, name='s', number=1).run(warmup=0)
41+
assert isinstance(result, BenchmarkResult)
42+
43+
def test_add_scenario_returns_group(self) -> None:
44+
s1 = Scenario(lambda: None, name='s1')
45+
s2 = Scenario(lambda: None, name='s2')
46+
group = s1 + s2
47+
assert isinstance(group, ScenarioGroup)
48+
49+
def test_add_group_returns_group(self) -> None:
50+
s1 = Scenario(lambda: None, name='s1')
51+
g = ScenarioGroup()
52+
group = s1 + g
53+
assert isinstance(group, ScenarioGroup)
54+
55+
56+
# ---------------------------------------------------------------------------
57+
# Negative type checks (runtime ValueError/TypeError for invalid inputs)
58+
# ---------------------------------------------------------------------------
59+
60+
class TestScenarioNegativeTypes:
61+
def test_number_zero_raises(self) -> None:
62+
with pytest.raises(ValueError):
63+
Scenario(lambda: None, name='s', number=0)
64+
65+
def test_number_negative_raises(self) -> None:
66+
with pytest.raises(ValueError):
67+
Scenario(lambda: None, name='s', number=-5)
68+
69+
def test_add_int_returns_not_implemented(self) -> None:
70+
s = Scenario(lambda: None, name='s')
71+
result = s.__add__(42) # type: ignore[arg-type]
72+
assert result is NotImplemented

0 commit comments

Comments
 (0)