pytest-tzshift
A tiny Pytest plug-in that automatically re-runs your tests under a matrix of time-zones and locales.
Why?
Time-zones and locales are global process settings.
If your code formats dates, parses user input, or depends on datetime.now(), it may behave differently on users' machines.
pytest-tzshift attempts to make these differences visible:
tests/test_format.py::test_human_readable[0|UTC|C] PASSED
tests/test_format.py::test_human_readable[1|America/New_York|C] PASSED
tests/test_format.py::test_human_readable[2|Europe/Berlin|de_DE] FAILED
Installation
pip install pytest-tzshift # requires Python ≥ 3.9
No further setup is necessary. The plug-in is auto-discovered by Pytest.
Quick start
Add the tzshift fixture to any test:
def test_price_formatting(tzshift):
tz, loc = tzshift # tuple-unpack
price = 1234.56
formatted = format_price(price) # your code
assert formatted.endswith("€") if loc.startswith("de_") else "€" not in formatted
Run Pytest as usual; each test will execute for every (timezone, locale) pair.
Default matrix
| Time-zones (IANA) | Locales (POSIX / glibc) |
|---|---|
UTC |
C |
America/New_York |
en_US.UTF-8 |
Europe/London |
de_DE.UTF-8 |
Asia/Kolkata |
fr_FR.UTF-8 |
Australia/Sydney |
ja_JP.UTF-8 |
Asia/Tokyo |
Unavailable zones/locales are skipped with a warning.
Customising the matrix
Project-wide (pytest.ini)
[pytest]
tz_timezones =
SYSTEM # keep OS default
Europe/Paris
tz_locales =
SYSTEM
fr_FR.UTF-8
tzshift_max = 10 # cap the total Cartesian product (0 = unlimited)
Command line
pytest --tz-timezones=UTC,Asia/Tokyo --tz-locales=C,ja_JP.UTF-8
pytest --tzshift-max=20
pytest --no-tzshift # disable for this run
Per-test marker
import pytest
@pytest.mark.tzshift(timezones=["UTC"], locales=["C"])
def test_once_only(tzshift):
...
@pytest.mark.tzshift(disable=True)
def test_native_env():
...
Platform notes
- On Windows,
time.tzset()is missing; the time-zone part becomes a no-op (locales still work). You'll still see separate parametrised runs, but all in the system zone. - Changing the process locale is global; avoid running
pytest-tzshiftwith parallel workers.
Documentation
- Quick start –
docs/usage/quickstart.md - Configuration details –
docs/usage/configuration.md - Markers & fixtures –
docs/usage/markers.md - API reference –
docs/reference/api.md
Browse the full site at https://spedr.github.io/pytest-tzshift once published.
Contributing
Bug reports, feature ideas, and pull requests are warmly welcome! See CONTRIBUTING for tips on setting up a dev environment, coding style, and running the test suite.
License
Released under the MIT License.
Metadata
Release files for pytest-tzshift 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pytest_tzshift-0.1.1.tar.gz | 14.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_tzshift-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 24.9 kB
Release files / pytest_tzshift-0.1.1.tar.gz
| Download URL | pytest_tzshift-0.1.1.tar.gz |
|---|---|
| Size | 14.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
37b3c539e98561f5b023ab855ce53389d4619c5750e35cc24ae1d457af082397
|
|
BLAKE2b-256 checksum How to use checksums |
eb675734b392d633c75abd255e3a47ae6c67db3b6e5a58cad3d7e012806070f9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.11
|
Release files / pytest_tzshift-0.1.1-py3-none-any.whl
| Download URL | pytest_tzshift-0.1.1-py3-none-any.whl |
|---|---|
| Size | 10.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7e2ade04672bbf899a497780e91e630ffc31c72f37bf28d420b6b717f1584e75
|
|
BLAKE2b-256 checksum How to use checksums |
0b966239e3e01f658b524e1d3f88e332e42bf52216180e32c0d66879753efa0d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.11
|