Search code examples
pythondatetimepytestfreezegun

How to pause pytest timer?


I have a parametrized (py)test that cleans up some table in the DB before running the logic:

@pytest.mark.parametrize('limit', [1, 1000, 5000000])
def test_calc(limit):
    # clean test table in database !!!
    assert calc(limit) == None

At the end of the tests I get:

=========== 3 passed in 357.65s (0:05:57) ===========

The problem is that about 2-3 minutes of that is the table cleanup.

How can I pause the timer before the cleanup and continue the timer after the cleanup finished ?

Like in Golang's testing library - T.StopTimer() & T.StartTime()

I searched all over google, and the closest thing I stumbled upon was freezegun.
I tried it out but couldn't get rid of the cleanup time, maybe I was using it somehow wrong :/
As far I understood it manipulates the datetime object but not pytest's timer (mechanism) :(


Solution

  • There is no timer to stop; pytest stores a timestamp on session start and prints the difference between the current time and the timestamp on session finish (if you're curious about the exact spot in the code where the duration is calculated, it's here). If the cleanup code is not tied to the rest of the test suite, you can move it into a custom impl of the pytest_unconfigure hook. Example:

    import time
    import pytest
    
    
    @pytest.fixture(autouse=True)
    def db():
        yield
        import time
        time.sleep(3)
    
    
    def test_db():
        assert True
    

    Running the test will yield

    ============================== 1 passed in 3.01s ==============================
    

    Moving the db cleanup to the hookimpl:

    # conftest.py
    
    import time
    
    
    def pytest_unconfigure(config):
        import time
        time.sleep(3)
    

    The reported duration is now

    ============================== 1 passed in 0.01s ==============================