如何在Python单元测试中模拟time.sleep()
我想做一个简单的替代方法,来阻止time.sleep(..)这个函数让程序暂停,以此来提高单元测试的执行速度。
我现在有的代码是:
import time as orgtime
class time(orgtime):
'''Stub for time.'''
_sleep_speed_factor = 1.0
@staticmethod
def _set_sleep_speed_factor(sleep_speed_factor):
'''Sets sleep speed.'''
time._sleep_speed_factor = sleep_speed_factor
@staticmethod
def sleep(duration):
'''Sleeps or not.'''
print duration * time._sleep_speed_factor
super.sleep(duration * time._sleep_speed_factor)
但是,在上面第二行代码(类定义)时,我遇到了以下错误:
TypeError: Error when calling the metaclass bases
module.__init__() takes at most 2 arguments (3 given).
怎么解决这个错误呢?
6 个回答
3
那这个怎么样:
import time
from time import sleep as originalsleep
def newsleep(seconds):
sleep_speed_factor = 10.0
originalsleep(seconds/sleep_speed_factor)
time.sleep = newsleep
这个对我有效。我把它放在我想加速的测试开始部分,最后再把原来的延迟设置回去,以防万一。希望这能帮到你。
7
这是我为了防止测试过程中出现暂停的情况所做的:
假设我有一个模块叫做 mymodule.py
,里面有一个函数使用了 sleep
,而我想对这个函数进行测试:
from time import sleep
def some_func()
sleep(5)
# ...do some things
接着,我在测试中从使用 sleep
的模块中导入它,像这样:
@mock.patch('mymodule.sleep')
def test_some_func(mock_sleep):
mock_sleep.return_value = None
# ...continue my test
16
我正在使用 pytest,并且有一个用于修改 time.sleep
的工具:
import pytest
@pytest.fixture
def sleepless(monkeypatch):
def sleep(seconds):
pass
monkeypatch.setattr(time, 'sleep', sleep)
然后在我需要“加速”睡眠的测试中,我只需使用这个工具:
import time
def test_sleep(sleepless):
time.sleep(60)
所以当你运行这个测试时,你会发现它完成的时间要短得多:
= 1 passed in 0.02 seconds =
19
被认可的答案仍然有效。不过,从Python 3.3开始,unittest.mock已经成为Python标准库的官方组成部分。
import time
from unittest import TestCase
from unittest.mock import patch
class TestMyCase(TestCase):
@patch('time.sleep', return_value=None)
def test_my_method(self, patched_time_sleep):
time.sleep(60) # Should be instant
# the mock should only be called once
self.assertEqual(1, patched_time_sleep.call_count)
# or
patched_time_sleep.assert_called_once()
# alternative version using a context manager
def test_my_method_alternative(self):
with patch('time.sleep', return_value=None) as patched_time_sleep:
time.sleep(60) # Should be instant
# the mock should only be called once
self.assertEqual(1, patched_time_sleep.call_count)
# or
patched_time_sleep.assert_called_once()
53
你可以在测试中使用 mock 这个库。
import time
from mock import patch
class MyTestCase(...):
@patch('time.sleep', return_value=None)
def my_test(self, patched_time_sleep):
time.sleep(666) # Should be instant