mirror of
https://github.com/jbranchaud/til
synced 2026-07-04 00:28:23 +00:00
Add Control Passing Of Time In Tests as a Python TIL
This commit is contained in:
@@ -10,7 +10,7 @@ working across different projects via [VisualMode](https://www.visualmode.dev/).
|
||||
|
||||
For a steady stream of TILs, [sign up for my newsletter](https://visualmode.kit.com/newsletter).
|
||||
|
||||
_1756 TILs and counting..._
|
||||
_1757 TILs and counting..._
|
||||
|
||||
See some of the other learning resources I work on:
|
||||
|
||||
@@ -1044,6 +1044,7 @@ If you've learned something here, support my efforts writing daily TILs by
|
||||
- [Access Most Recent Return Value In REPL](python/access-most-recent-return-value-in-repl.md)
|
||||
- [Break Debugger On First Line Of Program](python/break-debugger-on-first-line-of-program.md)
|
||||
- [Check If Package Is Installed With Pip](python/check-if-package-is-installed-with-pip.md)
|
||||
- [Control Passing Of Time In Tests](python/control-passing-of-time-in-tests.md)
|
||||
- [Create A Dummy DataFrame In Pandas](python/create-a-dummy-dataframe-in-pandas.md)
|
||||
- [Dunder Methods](python/dunder-methods.md)
|
||||
- [Easy Key-Value Aggregates With defaultdict](python/easy-key-value-aggregates-with-defaultdict.md)
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# Control Passing Of Time In Tests
|
||||
|
||||
While it is nice to be able to write pure functional code, our software still
|
||||
lives in the real world and may have to relate to or depend on the passing of
|
||||
time. In order to test this kind of code, we need time to behave in a reliable,
|
||||
deterministic way. One of the best ways to create a testing environment where
|
||||
that is true is to bring in tooling that hijacks time.
|
||||
|
||||
The [`freezegun` module](https://github.com/spulec/freezegun) is a great tool
|
||||
for that job. We can use it to freeze time at a specific testable point, advance
|
||||
time a specific amount, and much more.
|
||||
|
||||
Here is an example from the tests for [my CLI-based time tracking
|
||||
app](https://github.com/jbranchaud/py-vmt/blob/acb26e4840279d936a12f16c505ca7e75e9a6d20/tests/src/py_vmt/test_cli.py#L21)
|
||||
where I freeze time before starting a session. That gives me a chance to assert
|
||||
about the exact start time that is output by the command. Then I can advance
|
||||
time a little and assert that the `status` command outputs the correct thing.
|
||||
|
||||
```python
|
||||
import datetime
|
||||
from freezegun import freeze_time
|
||||
|
||||
# some other test setup omitted ...
|
||||
|
||||
initial_datetime = datetime.datetime(
|
||||
2026, 3, 14, 15, 5, 11, 0, datetime.timezone.utc
|
||||
)
|
||||
with freeze_time(initial_datetime) as frozen_datetime:
|
||||
# start a session
|
||||
start_result = runner.invoke(cli, ["start", "my-project"])
|
||||
output = "Started tracking 'my-project' at 10:05AM"
|
||||
assert output in start_result.output
|
||||
|
||||
frozen_datetime.tick(delta=datetime.timedelta(minutes=30))
|
||||
|
||||
# check status
|
||||
status_result = runner.invoke(cli, ["status"])
|
||||
output = "Tracking 'my-project' for 30m (since 10:05AM)"
|
||||
assert output in status_result.output
|
||||
```
|
||||
Reference in New Issue
Block a user