GitHubじゃ!Pythonじゃ!

GitHubからPython関係の優良リポジトリを探したかったのじゃー、でも英語は出来ないから日本語で読むのじゃー、英語社会世知辛いのじゃー

spulec

freezegun – あなたのPythonテストを時間をかけて行かせる

投稿日:

あなたのPythonテストを時間をかけて行かせる

FreezeGun:あなたのPythonテストを時間をかけて行かせる

FreezeGunは、Pythonテストがdatetimeモジュールを嘲笑することによって時間を遡ることを可能にするライブラリです。

使用法

デコレータまたはコンテキストマネージャが呼び出されると、datetime.datetime.now()、datetime.datetime.utcnow()、datetime.date.today()、time.time()、time.localtime()、time .gmtime()、time.strftime()は、フリーズした時刻を返します。

デコレータ

from freezegun import freeze_time
import datetime
import unittest


@freeze_time("2012-01-14")
def test():
    assert datetime.datetime.now() == datetime.datetime(2012, 1, 14)

# Or a unittest TestCase - freezes for every test, from the start of setUpClass to the end of tearDownClass

@freeze_time("1955-11-12")
class MyTests(unittest.TestCase):
    def test_the_class(self):
        assert datetime.datetime.now() == datetime.datetime(1955, 11, 12)

# Or any other class - freezes around each callable (may not work in every case)

@freeze_time("2012-01-14")
class Tester(object):
    def test_the_class(self):
        assert datetime.datetime.now() == datetime.datetime(2012, 1, 14)

コンテキストマネージャ

from freezegun import freeze_time

def test():
    assert datetime.datetime.now() != datetime.datetime(2012, 1, 14)
    with freeze_time("2012-01-14"):
        assert datetime.datetime.now() == datetime.datetime(2012, 1, 14)
    assert datetime.datetime.now() != datetime.datetime(2012, 1, 14)

生の使用

from freezegun import freeze_time

freezer = freeze_time("2012-01-14 12:00:01")
freezer.start()
assert datetime.datetime.now() == datetime.datetime(2012, 1, 14, 12, 0, 1)
freezer.stop()

時間帯

from freezegun import freeze_time

@freeze_time("2012-01-14 03:21:34", tz_offset=-4)
def test():
    assert datetime.datetime.utcnow() == datetime.datetime(2012, 1, 14, 3, 21, 34)
    assert datetime.datetime.now() == datetime.datetime(2012, 1, 13, 23, 21, 34)

    # datetime.date.today() uses local time
    assert datetime.date.today() == datetime.date(2012, 1, 13)

@freeze_time("2012-01-14 03:21:34", tz_offset=-datetime.timedelta(hours=3, minutes=30))
def test_timedelta_offset():
    assert datetime.datetime.now() == datetime.datetime(2012, 1, 13, 23, 51, 34)

良い入力

FreezeGunは舞台裏でdateutilを使用していますので、素敵な日時を持つことができます。

@freeze_time("Jan 14th, 2012")
def test_nice_datetime():
    assert datetime.datetime.now() == datetime.datetime(2012, 1, 14)

関数とジェネレータオブジェクト

FreezeGunは関数オブジェクトとジェネレータオブジェクトを扱うことができます。

def test_lambda():
    with freeze_time(lambda: datetime.datetime(2012, 1, 14)):
        assert datetime.datetime.now() == datetime.datetime(2012, 1, 14)

def test_generator():
    datetimes = (datetime.datetime(year, 1, 1) for year in range(2010, 2012))

    with freeze_time(datetimes):
        assert datetime.datetime.now() == datetime.datetime(2010, 1, 1)

    with freeze_time(datetimes):
        assert datetime.datetime.now() == datetime.datetime(2011, 1, 1)

    # The next call to freeze_time(datetimes) would raise a StopIteration exception.

tick引数

FreezeGunには、指定された値で時間を再開させる追加のtick引数がありますが、その後は時間が刻々と変化します。 これは、時間を停止し続けるデフォルトのパラメータの代わりです。

@freeze_time("Jan 14th, 2020", tick=True)
def test_nice_datetime():
    assert datetime.datetime.now() > datetime.datetime(2020, 1, 14)

マニュアルティック

FreezeGunでは、手動で転送することもできます。

def test_manual_increment():
    initial_datetime = datetime.datetime(year=1, month=7, day=12,
                                        hour=15, minute=6, second=3)
    with freeze_time(initial_datetime) as frozen_datetime:
        assert frozen_datetime() == initial_datetime

        frozen_datetime.tick()
        initial_datetime += datetime.timedelta(seconds=1)
        assert frozen_datetime() == initial_datetime

        frozen_datetime.tick(delta=datetime.timedelta(seconds=10))
        initial_datetime += datetime.timedelta(seconds=10)
        assert frozen_datetime() == initial_datetime

日時を指定するための移動時間

FreezeGunでは、特定の日付に移動する時間を許可します。

def test_move_to():
    initial_datetime = datetime.datetime(year=1, month=7, day=12,
                                        hour=15, minute=6, second=3)

    other_datetime = datetime.datetime(year=2, month=8, day=13,
                                        hour=14, minute=5, second=0)
    with freeze_time(initial_datetime) as frozen_datetime:
        assert frozen_datetime() == initial_datetime

        frozen_datetime.move_to(other_datetime)
        assert frozen_datetime() == other_datetime

        frozen_datetime.move_to(initial_datetime)
        assert frozen_datetime() == initial_datetime


@freeze_time("2012-01-14", as_arg=True)
def test(frozen_time):
    assert datetime.datetime.now() == datetime.datetime(2012, 1, 14)
    frozen_time.move_to("2014-02-12")
    assert datetime.datetime.now() == datetime.datetime(2014, 2, 12)

move_toパラメータは、任意の有効なfreeze_time日付(文字列、日付、日時)にすることができます。

デフォルトの引数

FreezeGunはデフォルトの引数を変更しないことに注意してください。 次のコードは、現在の日付を出力します。 理由はこちらをご覧ください。

from freezegun import freeze_time
import datetime as dt

def test(default=dt.date.today()):
    print(default)

with freeze_time('2000-1-1'):
    test()

インストール

FreezeGunをインストールするには、次のようにします。

$ pip install freezegun

Debian(テストと不安定)システム:

$ sudo apt-get install python-freezegun







-spulec

執筆者: