Вопрос: Как насмехаться / установить системную дату в pytest?


В некоторых моих тестах у меня возникает проблема, что они терпят неудачу в Travis из-за проблем с часовым поясом и часовым поясом, поэтому я хочу высмеять системное время для моего теста. Как я могу это сделать?


6


источник


Ответы:


AFAIK, вы не можете издеваться над встроенными методами.

Один из подходов, который я часто делал, - немного изменить мой код, чтобы не использовать datetime непосредственно для получения даты, но где-то функция-обертка:

# mymodule.py

def get_today():
   return datetime.date.today()

Это делает тривиальным просто mock это в вашем тесте:

def test_something():
    with mock.patch('mymodule.get_today', return_value=datetime.date(2014, 6, 2)):
        ...

Вы также можете использовать freezegun  модуль.


9



Это можно сделать двумя способами:

  1. Создайте функцию, которую вы вызовете вместо datetime.datetime.now() как было предложено Бруно, но здесь есть другая реализация:

    import os
    import datetime
    
    def mytoday():
     if 'MYDATE' in os.environ:
         return datetime.datetime.strptime(os.getenv('MYDATE'), '%m-%d-%Y').date()
     else:
         return datetime.date.today()
    

    Затем, в вашем тесте, вы просто переменная среды monkeypatch:

    import datetime
    
    def test_patched_date(monkeypatch):
        monkeytest.setenv('MYDATE', '05-31-2014')
        assert datetime.date.today() == datetime.date(2014, 5, 31)
    
  2. Monkeypatch datetime функция:

    import datetime
    import pytest
    
    FAKE_TIME = datetime.datetime(2020, 12, 25, 17, 05, 55)
    
    @pytest.fixture
    def patch_datetime_now(monkeypatch):
    
        class mydatetime:
            @classmethod
            def now(cls):
                return FAKE_TIME
    
        monkeypatch.setattr(datetime, 'datetime', mydatetime)
    
    
    def test_patch_datetime(patch_datetime_now):
        assert datetime.datetime.now() == FAKE_TIME
    

8



Ответ Брайана-Крюгера - лучший. Я проголосовал за его восстановление. В это время...

использование freezegun  ( Сделки рЕПО ).

Из README:

from freezegun import freeze_time

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

2