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 ====