Pythonで日付まわりをテストする場合、日付を固定できる freezegun
が便利です。
spulec/freezegun: Let your Python tests travel through time
また、pytestの場合、pytestのプラグインとして pytest-freezegun
があります。
ktosiek/pytest-freezegun: Easily freeze time in pytest test + fixtures
これを使うことで、pytestのmarkerとして @pytest.mark.freeze_time
が追加されます。
そのため、markerを使うだけで、現在時刻が固定されます。
from datetime import datetime import pytest @pytest.mark.freeze_time('2018-02-03 1:23:45') def test_time(): assert datetime.today() == datetime(2018, 2, 3, 1, 23, 45)
実行結果
$ pytest ==== test session starts ==== platform darwin -- Python 3.7.2, pytest-3.7.4, py-1.7.0, pluggy-0.8.1 rootdir: /path/to/dir, inifile: plugins: freezegun-0.2.0 collected 1 item test_time.py . [100%] ==== 1 passed in 0.07 seconds ====
そんな中、pytestを3.7.4から4.1.1へとアップデートしたところ、エラーが出ました。
# バージョン確認 $ pip list Package Version ---------------- ------- pytest 3.7.4 pytest-freezegun 0.2.0 # アップデート $ pip install -U pytest ... Successfully installed pytest-4.2.0 # テストを実行すると、エラー $ pytest ===== test session starts ==== platform darwin -- Python 3.7.2, pytest-4.2.0, py-1.7.0, pluggy-0.8.1 rootdir: /path/to/dir, inifile: plugins: freezegun-0.2.0 collected 1 item test_time.py E [100%] ==== ERRORS ==== ____ ERROR at setup of test_time ____ self = <pytest_freezegun.FreezegunPlugin object at 0x10dbea588>, item = <Function test_time> @pytest.hookimpl(tryfirst=True) def pytest_runtest_setup(self, item): > marker = item.get_marker('freeze_time') E AttributeError: 'Function' object has no attribute 'get_marker' env/lib/python3.7/site-packages/pytest_freezegun.py:23: AttributeError
そこで、対応したことをメモとして残します。
環境
- Python 3.7.2
- pytest 3.10.1 からpytest 4.1.1 へアップデート
- pytest-freezegun 0.2.0
対応
公式にissueがありました。pytest-freezegun の新しいバージョンで対応したようです。
pytest4.0 released and pytest-freezegun can't work. · Issue #7 · ktosiek/pytest-freezegun
そのため、pytest-freezegunをアップデートしたところ、問題なく動作するようになりました。
$ pip install -U pytest-freezegun ... Successfully installed pytest-freezegun-0.3.0.post1 # テストを再実行 $ pytest ==== test session starts ==== platform darwin -- Python 3.7.2, pytest-4.2.0, py-1.7.0, pluggy-0.8.1 rootdir: /path/to/dir, inifile: plugins: freezegun-0.3.0.post1 collected 1 item test_time.py . [100%] ==== 1 passed in 0.08 seconds ====