Skip to content

Commit 251f303

Browse files
Евгений БлиновЕвгений Блинов
authored andcommitted
Tests for docs
1 parent faaa395 commit 251f303

1 file changed

Lines changed: 156 additions & 0 deletions

File tree

tests/documentation/test_readme.py

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
from __future__ import annotations
2+
3+
import math
4+
from functools import partial
5+
6+
from microbenchmark import BenchmarkResult, Scenario, ScenarioGroup
7+
8+
9+
class TestQuickStart:
10+
def test_quick_start_basic(self) -> None:
11+
def build_list() -> list[int]:
12+
return list(range(1000))
13+
14+
scenario = Scenario(build_list, name='build_list', number=500)
15+
result = scenario.run()
16+
assert len(result.durations) == 500
17+
assert isinstance(result.mean, float)
18+
assert isinstance(result.best, float)
19+
assert isinstance(result.worst, float)
20+
21+
22+
class TestScenarioConstructor:
23+
def test_full_constructor(self) -> None:
24+
scenario = Scenario(
25+
sorted,
26+
args=[[3, 1, 2]],
27+
name='sort_three_items',
28+
doc='Sort a list of three integers.',
29+
number=10000,
30+
)
31+
assert scenario.name == 'sort_three_items'
32+
assert scenario.doc == 'Sort a list of three integers.'
33+
assert scenario.number == 10000
34+
35+
def test_partial_kwargs(self) -> None:
36+
scenario = Scenario(
37+
partial(sorted, key=lambda x: -x),
38+
args=[[3, 1, 2]],
39+
name='sort_descending',
40+
)
41+
result = scenario.run()
42+
assert isinstance(result, BenchmarkResult)
43+
44+
def test_multiple_positional_args(self) -> None:
45+
scenario = Scenario(pow, args=[2, 10], name='power')
46+
result = scenario.run()
47+
assert isinstance(result.mean, float)
48+
49+
50+
class TestScenarioRun:
51+
def test_run_with_warmup(self) -> None:
52+
scenario = Scenario(lambda: list(range(100)), name='build', number=1000)
53+
result = scenario.run(warmup=100)
54+
assert len(result.durations) == 1000
55+
56+
57+
class TestScenarioGroupCreation:
58+
def test_direct_construction(self) -> None:
59+
s1 = Scenario(lambda: None, name='s1')
60+
s2 = Scenario(lambda: None, name='s2')
61+
group = ScenarioGroup(s1, s2)
62+
assert isinstance(group, ScenarioGroup)
63+
64+
def test_empty_group(self) -> None:
65+
empty = ScenarioGroup()
66+
assert len(empty.run()) == 0
67+
68+
def test_plus_operator_two_scenarios(self) -> None:
69+
s1 = Scenario(lambda: None, name='s1')
70+
s2 = Scenario(lambda: None, name='s2')
71+
group = s1 + s2
72+
assert type(group).__name__ == 'ScenarioGroup'
73+
74+
def test_scenario_plus_group(self) -> None:
75+
s1 = Scenario(lambda: None, name='s1')
76+
s2 = Scenario(lambda: None, name='s2')
77+
s3 = Scenario(lambda: None, name='s3')
78+
group = ScenarioGroup(s1, s2)
79+
extended = group + s3
80+
assert len(extended.run()) == 3
81+
82+
def test_reverse_scenario_plus_group(self) -> None:
83+
s1 = Scenario(lambda: None, name='s1')
84+
s2 = Scenario(lambda: None, name='s2')
85+
s3 = Scenario(lambda: None, name='s3')
86+
group = ScenarioGroup(s1, s2)
87+
also_ok = s3 + group
88+
assert len(also_ok.run()) == 3
89+
90+
def test_group_plus_group(self) -> None:
91+
s1 = Scenario(lambda: None, name='s1')
92+
s2 = Scenario(lambda: None, name='s2')
93+
s3 = Scenario(lambda: None, name='s3')
94+
g1 = ScenarioGroup(s1)
95+
g2 = ScenarioGroup(s2, s3)
96+
combined = g1 + g2
97+
assert len(combined.run()) == 3
98+
99+
100+
class TestScenarioGroupRun:
101+
def test_run_order_preserved(self) -> None:
102+
s1 = Scenario(lambda: None, name='s1')
103+
s2 = Scenario(lambda: None, name='s2')
104+
group = ScenarioGroup(s1, s2)
105+
results = group.run(warmup=50)
106+
assert results[0].scenario.name == 's1'
107+
assert results[1].scenario.name == 's2'
108+
109+
110+
class TestBenchmarkResultFields:
111+
def test_fields_documentation_example(self) -> None:
112+
result = Scenario(lambda: None, name='noop', number=100).run()
113+
assert len(result.durations) == 100
114+
assert result.is_primary is True
115+
116+
def test_durations_is_tuple(self) -> None:
117+
result = Scenario(lambda: None, name='noop', number=100).run()
118+
assert isinstance(result.durations, tuple)
119+
120+
121+
class TestPercentile:
122+
def test_percentile_documentation_example(self) -> None:
123+
result = Scenario(lambda: None, name='noop', number=100).run()
124+
trimmed = result.percentile(95)
125+
assert trimmed.is_primary is False
126+
assert len(trimmed.durations) == math.ceil(100 * 95 / 100)
127+
128+
def test_percentile_chaining(self) -> None:
129+
result = Scenario(lambda: None, name='noop', number=100).run()
130+
chained = result.percentile(90).percentile(50)
131+
assert len(chained.durations) == math.ceil(math.ceil(100 * 90 / 100) * 50 / 100)
132+
133+
134+
class TestP95P99:
135+
def test_p95_cached(self) -> None:
136+
result = Scenario(lambda: None, name='noop', number=100).run()
137+
assert len(result.p95.durations) == math.ceil(100 * 95 / 100)
138+
assert result.p95.is_primary is False
139+
assert result.p95 is result.p95
140+
141+
def test_p99_cached(self) -> None:
142+
result = Scenario(lambda: None, name='noop', number=100).run()
143+
assert len(result.p99.durations) == math.ceil(100 * 99 / 100)
144+
assert result.p99.is_primary is False
145+
assert result.p99 is result.p99
146+
147+
148+
class TestJsonRoundTrip:
149+
def test_json_round_trip(self) -> None:
150+
result = Scenario(lambda: None, name='noop', number=100).run()
151+
json_str = result.to_json()
152+
restored = BenchmarkResult.from_json(json_str)
153+
assert restored.scenario is None
154+
assert restored.mean == result.mean
155+
assert restored.durations == result.durations
156+
assert restored.is_primary == result.is_primary

0 commit comments

Comments
 (0)