Uncategorized

Time Travel, unittest.mock, freezegun and monkeypatch

To test time-dependant programs, such as timelapse camera, we can fudge the system time (sleep,. now()) in Python. Some options are:

An example using freezegun and monkeypatch

# chilly_bin_test.py
#
from freezegun import freeze_time
import time
import another_module

def test_capture(monkeypatch):  
    # fake time with freezegun
    with freeze_time(parse("2000-01-01 00:00:00")) as frozen_datetime:
        def sleepless(s):
            """ instead of really sleeping, just move frozen time forward """
            td = timedelta(seconds=s)
            frozen_datetime.tick(td)
        c1 = Camera()
        c1.config("./camera_app/tests/camera-test-config-1.toml")
        # replace real camera will a dummy using Mock. Could also use monkeypatch (?)
        c1._camera = unittest.mock.MagicMock(capture=True)
        # fake sleeping using monkeypatch
        monkeypatch.setattr(time, 'sleep', sleepless)
        # Now time.sleep() runs sleepless():
        time.sleep(10) #  locally ...
        c1.run(3)      # and works in another module 

# another_module.py
#
import time # careful will naming of time, datetime, etc because
            # there is also a datetime.datetime.sleep

class Camera():
    def run(n):
        time.sleep(10) # won't really sleep! use full name

An example of time changing using mock:

import unittest.mock
from datetime import datetime # for local use

# normally in another module
def thing_to_test():
    from datetime import datetime # load so can be patched !!!
    print("thing_to_test: {}".format(datetime.now()))
    print("thing_to_test: {}".format(datetime.now()))

ts = [datetime(2000, 1, 1, 1, 1, 1), datetime(2000, 1, 2, 1, 1, 1)]

@unittest.mock.patch('datetime.datetime')
def test2(self):
    self.now.side_effect = ts   
    thing_to_test()

test2()

Leave a Reply

Your email address will not be published. Required fields are marked *