如何在pytest中模拟/设置系统日期?

时间:2014-06-02 06:57:41

标签: python pytest

在我的一些测试中,由于时间和时区问题,我遇到了Travis失败的问题,所以我想模拟系统时间进行测试。我怎么能这样做?

3 个答案:

答案 0 :(得分:11)

有两种方法可以实现这一目标:

  1. 按照Bruno的建议创建您将调用的函数而不是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
    

答案 1 :(得分:10)

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模块。

答案 2 :(得分:5)

@ Brian-Kruger的答案是最好的答案。我已经投票取消删除它。在此期间......

使用freezegunrepo)。

来自自述文件:

from freezegun import freeze_time

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