How to unit test a function containing the current time using freezegun in python

Hello sekitaka.

Today I'll show you how to test a function that uses datetime.now ().

For example, suppose you want to create a function that returns the string "YYYYMMDD" the next day after running a program and test that function.

def get_tomorrow():
    now_datetime = datetime.now()
    tomorrow_datetime = now_datetime + timedelta(days=+1)
    tomorrow = tomorrow_datetime.strftime("%Y%m%d")
    return tomorrow

Test method

Proposal 1

First, I briefly wrote the following test code. But as you can see, it only succeeds if you run the test on June 22, 2017. This will result in an error when testing daily with CI.

class Test(TestCase):
    def test_get_tomorrow(self):
        self.assertEqual("20170623", get_tomorrow())

Proposal 2

The next idea was to dynamically generate the expected value. This will pass the test whenever you test it. However, in fact, I wrote the same code as get_tomorrow, and I feel that it has not been tested.

class Test(TestCase):
    def test_get_tomorrow(self):
        expect_tomorrow = (datetime.now() + timedelta(days=+1)).strftime("%Y%m%d")
        self.assertEqual(expect_tomorrow, get_tomorrow())

Proposal 3

Therefore, I thought that it would be better to Mock datetime.now (), set it to return an arbitrary datetime, and execute get_tomorrow. And I wrote the following code.

from mock import Mock
class Test(TestCase):
    def test_get_tomorrow(self):
        datetime.now = Mock(return_value=datetime(year=2017, month=1, day=1))
        self.assertEqual("20170102", get_tomorrow())

When I ran it with expectation, it seemed that I couldn't set attribute to the built-in datetime, so I couldn't run it.

TypeError: can't set attributes of built-in/extension type 'datetime.datetime'

Proposal 4 (answer)

When I was in trouble, I found a library called freezegun that mocked the datetime module.

from freezegun import freeze_time
class Test(TestCase):
    @freeze_time("2017-01-01")
    def test_get_tomorrow_4(self):
        self.assertEqual("20170102", get_tomorrow())

The current is fixed to 2017/1/1 by the description of @freeze_time ("2017-01-01 "). So get_tomorrow () will always return " 20170102 " and will succeed whenever you run the test. If you change the freeze_time date, you can check whether the program works normally over a year or in a leap year, which is convenient.

Summary

What did you think. I introduced how to test a function that depends on python's datetime.now (). It is necessary to create a test case so that unit tests can be executed once and not finished, but can be executed at any time if CI is turned. I would like to continue learning about test methods.

Recommended Posts

How to unit test a function containing the current time using freezegun in python
How to know the current directory in Python in Blender
How to execute a command using subprocess in Python
[Circuit x Python] How to find the transfer function of a circuit using Lcapy
How to use the __call__ method in a Python class
How to generate a query using the IN operator in Django
To return char * in a callback function using ctypes in Python
How to get the last (last) value in a list in Python
How to test the current time with Go (I made a very thin library)
How to determine the existence of a selenium element in Python
How to check the memory size of a variable in Python
[Introduction to Python] How to use the in operator in a for statement?
How to check the memory size of a dictionary in Python
A function that measures the processing time of a method in python
[Python3] Define a decorator to measure the execution time of a function
Write the test in a python docstring
How to get a stacktrace in python
How to divide and process a data frame using the groupby function
How to get the date and time difference in seconds with python
How to get a value from a parameter store in lambda (using python)
[Introduction to Python] How to write a character string with the format function
A useful note when using Python for the first time in a while
Python: I want to measure the processing time of a function neatly
How to sort by specifying a column in the Python Numpy array.
How to stop a program in python until a specific date and time
How to use the C library in Python
How to clear tuples in a list (Python)
To execute a Python enumerate function in JavaScript
How to embed a variable in a python string
Get the caller of a function in Python
How to create a JSON file in Python
A clever way to time processing in Python
How to notify a Discord channel in Python
How to get the files in the [Python] folder
[Python] How to draw a histogram in Matplotlib
How to Mock a Public function in Pytest
[2015/11/19] How to register a service locally using the python SDK on naoqi os
How to pass the execution result of a shell command in a list in Python
[AWS] Let's run a unit test of Lambda function in the local environment
[Python] Smasher tried to make the video loading process a function using a generator
Continue to retrieve tweets containing specific keywords using the Streaming API in Python
How to get a list of files in the same directory with python
How to retrieve the nth largest value in Python
How to convert / restore a string with [] in python
How to get the variable name itself in python
How to write a GUI using the maya command
How to get the number of digits in Python
How to set up a Python environment using pyenv
[Introduction to Python] How to iterate with the range function?
I want to write in Python! (2) Let's write a test
[Python] How to expand variables in a character string
How to make a Python package using VS Code
How to exit when using Python in Terminal (Mac)
How to use the model learned in Lobe in Python
Write code to Unit Test a Python web app
How to retrieve multiple arrays using slice in python.
[Introduction to Python] How to stop the loop using break?
[Python] How to output the list values in order
How to read csv containing only integers in Python
[Python] How to call a c function from python (ctypes)
What does the last () in a function mean in Python?