Skip to content

Commit a2fcf8a

Browse files
chore: MockTiming - move impl to _pytest.timing
1 parent 20c558c commit a2fcf8a

File tree

2 files changed

+37
-19
lines changed

2 files changed

+37
-19
lines changed

src/_pytest/timing.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,46 @@
55
66
Fixture "mock_timing" also interacts with this module for pytest's own tests.
77
"""
8-
98
from __future__ import annotations
109

10+
import dataclasses
11+
from datetime import datetime
1112
from time import perf_counter
1213
from time import sleep
1314
from time import time
15+
from typing import TYPE_CHECKING
16+
17+
18+
if TYPE_CHECKING:
19+
from pytest import MonkeyPatch
20+
21+
22+
@dataclasses.dataclass
23+
class MockTiming:
24+
"""Mocks _pytest.timing with a known object that can be used to control timing in tests
25+
deterministically.
26+
27+
pytest itself should always use functions from `_pytest.timing` instead of `time` directly.
28+
29+
This then allows us more control over time during testing, if testing code also
30+
uses `_pytest.timing` functions.
31+
32+
Time is static, and only advances through `sleep` calls, thus tests might sleep over large
33+
numbers and obtain accurate time() calls at the end, making tests reliable and instant."""
34+
35+
_current_time: float = datetime(2020, 5, 22, 14, 20, 50).timestamp() # noqa: RUF009
36+
37+
def sleep(self, seconds: float) -> None:
38+
self._current_time += seconds
39+
40+
def time(self) -> float:
41+
return self._current_time
42+
43+
def patch(self, monkeypatch: MonkeyPatch) -> None:
44+
from _pytest import timing
45+
monkeypatch.setattr(timing, "sleep", self.sleep)
46+
monkeypatch.setattr(timing, "time", self.time)
47+
monkeypatch.setattr(timing, "perf_counter", self.time)
1448

1549

1650
__all__ = ["perf_counter", "sleep", "time"]

testing/conftest.py

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -226,24 +226,8 @@ def mock_timing(monkeypatch: MonkeyPatch):
226226
Time is static, and only advances through `sleep` calls, thus tests might sleep over large
227227
numbers and obtain accurate time() calls at the end, making tests reliable and instant.
228228
"""
229-
230-
@dataclasses.dataclass
231-
class MockTiming:
232-
_current_time: float = 1590150050.0
233-
234-
def sleep(self, seconds: float) -> None:
235-
self._current_time += seconds
236-
237-
def time(self) -> float:
238-
return self._current_time
239-
240-
def patch(self) -> None:
241-
from _pytest import timing
242-
243-
monkeypatch.setattr(timing, "sleep", self.sleep)
244-
monkeypatch.setattr(timing, "time", self.time)
245-
monkeypatch.setattr(timing, "perf_counter", self.time)
229+
from _pytest.timing import MockTiming
246230

247231
result = MockTiming()
248-
result.patch()
232+
result.patch(monkeypatch)
249233
return result

0 commit comments

Comments
 (0)