chore: MockTiming - move impl to _pytest.timing

This commit is contained in:
Ronny Pfannschmidt 2024-02-21 16:16:34 +01:00
parent 20c558c84a
commit 96b786b63b
2 changed files with 38 additions and 19 deletions

View File

@ -8,9 +8,45 @@ Fixture "mock_timing" also interacts with this module for pytest's own tests.
from __future__ import annotations from __future__ import annotations
import dataclasses
from datetime import datetime
from time import perf_counter from time import perf_counter
from time import sleep from time import sleep
from time import time from time import time
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from pytest import MonkeyPatch
@dataclasses.dataclass
class MockTiming:
"""Mocks _pytest.timing with a known object that can be used to control timing in tests
deterministically.
pytest itself should always use functions from `_pytest.timing` instead of `time` directly.
This then allows us more control over time during testing, if testing code also
uses `_pytest.timing` functions.
Time is static, and only advances through `sleep` calls, thus tests might sleep over large
numbers and obtain accurate time() calls at the end, making tests reliable and instant."""
_current_time: float = datetime(2020, 5, 22, 14, 20, 50).timestamp() # noqa: RUF009
def sleep(self, seconds: float) -> None:
self._current_time += seconds
def time(self) -> float:
return self._current_time
def patch(self, monkeypatch: MonkeyPatch) -> None:
from _pytest import timing # noqa: PLW0406
monkeypatch.setattr(timing, "sleep", self.sleep)
monkeypatch.setattr(timing, "time", self.time)
monkeypatch.setattr(timing, "perf_counter", self.time)
__all__ = ["perf_counter", "sleep", "time"] __all__ = ["perf_counter", "sleep", "time"]

View File

@ -1,7 +1,6 @@
# mypy: allow-untyped-defs # mypy: allow-untyped-defs
from __future__ import annotations from __future__ import annotations
import dataclasses
import re import re
import sys import sys
from typing import Generator from typing import Generator
@ -226,24 +225,8 @@ def mock_timing(monkeypatch: MonkeyPatch):
Time is static, and only advances through `sleep` calls, thus tests might sleep over large Time is static, and only advances through `sleep` calls, thus tests might sleep over large
numbers and obtain accurate time() calls at the end, making tests reliable and instant. numbers and obtain accurate time() calls at the end, making tests reliable and instant.
""" """
from _pytest.timing import MockTiming
@dataclasses.dataclass
class MockTiming:
_current_time: float = 1590150050.0
def sleep(self, seconds: float) -> None:
self._current_time += seconds
def time(self) -> float:
return self._current_time
def patch(self) -> None:
from _pytest import timing
monkeypatch.setattr(timing, "sleep", self.sleep)
monkeypatch.setattr(timing, "time", self.time)
monkeypatch.setattr(timing, "perf_counter", self.time)
result = MockTiming() result = MockTiming()
result.patch() result.patch(monkeypatch)
return result return result