Skip to content

Commit 18a8351

Browse files
committed
Some docs
1 parent ccc66d1 commit 18a8351

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

README.rst

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,120 @@ pytest-time
33

44
The pytest-time plugin extends pytest to control ``time`` — the built-in Python
55
module, not the concept within the universe.
6+
7+
Fixtures
8+
--------
9+
10+
Pytest-time offers several fixtures for use in your projects, depending on your particular needs.
11+
12+
Instant Sleep
13+
~~~~~~~~~~~~~
14+
15+
The ``instant_sleep`` fixture is the most basic wrapper and is designed to be used at any scope. It monkeypatches the built-in ``time`` module to be chronologically consistent while not actually sleeping when running ``time.sleep``. This includes modifying the behaviour of ``time.time()``, ``time.monotonic()`` and their nanosecond counterparts to include the additional delay expected after sleeping.
16+
17+
A basic use of ``instant_sleep`` is shown below:
18+
19+
.. code:: python
20+
:number-lines:
21+
22+
import time
23+
import pytest
24+
25+
@pytest.mark.parametrize("sleep_time", [1, 10, 100])
26+
@pytest.mark.usefixtures("instant_sleep")
27+
def test_instant_sleep(sleep_time):
28+
start_time = time.time()
29+
start_monotonic = time.monotonic()
30+
31+
time.sleep(sleep_time)
32+
33+
assert time.time() >= start_time + sleep_time
34+
assert time.monotonic() >= start_monotonic + sleep_time
35+
36+
This code will behave almost identically with and without the ``instant_sleep`` fixture in use. To demonstrate, let's time this file with the fixture enabled...
37+
38+
.. code:: text
39+
40+
$ time pytest test_instant_sleep.py
41+
=========== test session starts ===========
42+
platform linux -- Python 3.11.4, pytest-7.3.1, pluggy-1.0.0
43+
rootdir: /home/lengau/Projects/pytest-time
44+
configfile: pyproject.toml
45+
plugins: check-2.1.5, mock-3.10.0, hypothesis-6.78.2, time-0.2.1.dev3+ga0d3b98.d20230624, cov-4.1.0
46+
collected 3 items
47+
48+
test_instant_sleep.py ... [100%]
49+
50+
=========== 3 passed in 0.01s ===========
51+
52+
real 0m0.276s
53+
user 0m0.240s
54+
sys 0m0.025s
55+
56+
and disabled:
57+
58+
.. code:: text
59+
60+
$ time pytest test_instant_sleep_no_fixture.py
61+
=========== test session starts ===========
62+
platform linux -- Python 3.11.4, pytest-7.3.1, pluggy-1.0.0
63+
rootdir: /home/lengau/Projects/pytest-time
64+
configfile: pyproject.toml
65+
plugins: check-2.1.5, mock-3.10.0, hypothesis-6.78.2, time-0.2.1.dev3+ga0d3b98.d20230624, cov-4.1.0
66+
collected 3 items
67+
68+
test_instant_sleep_no_fixture.py ... [100%]
69+
70+
=========== 3 passed in 111.01s (0:01:51) ===========
71+
72+
real 1m51.354s
73+
user 0m0.250s
74+
sys 0m0.020s
75+
76+
The sleep is, for practical purposes, essentially instant. And yet, the ``time`` module still acts as though the appropriate time has passed.
77+
78+
Recording Time Calls
79+
~~~~~~~~~~~~~~~~~~~~~
80+
81+
Pytest-time also provides ``mock_time``, a fixture that wraps several ``time`` functions in Mock objects but still runs the real calls. This is useful if you need to ensure that certain calls occurred, etc. The fixture will provide Mock objects for inspection in tests:
82+
83+
.. code:: python
84+
:number-lines:
85+
86+
import time
87+
88+
def test_mock_time(mock_time):
89+
start_time = time.time()
90+
start_monotonic = time.monotonic()
91+
92+
time.sleep(1) # Actually sleeps for a second
93+
94+
assert time.time() >= start_time + 1
95+
assert time.monotonic() >= start_monotonic + 1
96+
97+
mock_time.sleep.assert_called_once_with(1)
98+
assert len(mock_time.time.mock_calls) == 2
99+
assert len(mock_time.monotonic.mock_calls) == 2
100+
101+
Mocking a Powernap
102+
~~~~~~~~~~~~~~~~~~
103+
104+
The two above are combined for you in the ``mock_instant_sleep`` fixture. This fixture replaces the relevant ``time`` functions as in the ```instant_sleep`` fixture, but also provides mock wrappers around those functions, allowing for recording time.
105+
106+
.. code:: python
107+
:number-lines:
108+
109+
import time
110+
111+
def test_mock_instant_sleep(mock_instant_sleep):
112+
start_time = time.time()
113+
start_monotonic = time.monotonic()
114+
115+
time.sleep(86400) # Doesn't sleep
116+
117+
assert time.time() >= start_time + 86400
118+
assert time.monotonic() >= start_monotonic + 86400
119+
120+
mock_instant_sleep.sleep.assert_called_once_with(1)
121+
assert len(mock_instant_sleep.time.mock_calls) == 2
122+
assert len(mock_instant_sleep.monotonic.mock_calls) == 2

0 commit comments

Comments
 (0)