如何在Python单元测试中存根time.sleep()

Mic*_*ers 16 python time constructor class python-unittest

我想制作一个存根来防止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) 
Run Code Online (Sandbox Code Playgroud)

但是,我在上面的第二个代码行(类定义)上收到以下错误:

TypeError: Error when calling the metaclass bases
module.__init__() takes at most 2 arguments (3 given).
Run Code Online (Sandbox Code Playgroud)

如何修复错误?

Mik*_*maa 31

您可以在测试中使用模拟库.

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
Run Code Online (Sandbox Code Playgroud)

  • 这是您组织内的社会问题.我建议您将此决定交给您的团队,并解释使用最佳实践单元测试工具的好处,以提高开发效率.如果他们不相信你,你可以告诉你一个随机的老兄告诉你:)因为替代方案是从模拟库中删除代码而且这很糟糕. (7认同)
  • mock是PyPi上可用的开源Python库,适用于每个平台.通常不应存在任何实际,法律或任何其他问题,包括或嵌入此类库. (6认同)

Jee*_*ler 10

接受的答案仍然有效。然而,unittest.mock从 Python 3.3 开始成为 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()
Run Code Online (Sandbox Code Playgroud)


sas*_*shk 6

我正在使用pytest并有以下固定装置来猴子补丁time.sleep

import pytest


@pytest.fixture
def sleepless(monkeypatch):

    def sleep(seconds):
        pass

    monkeypatch.setattr(time, 'sleep', sleep)
Run Code Online (Sandbox Code Playgroud)

然后在我需要“加速”睡眠的测试中,我只使用这个夹具:

import time

def test_sleep(sleepless):
    time.sleep(60)
Run Code Online (Sandbox Code Playgroud)

因此,当您运行此测试时,您会看到它在更短的时间内完成:

= 1 passed in 0.02 seconds =
Run Code Online (Sandbox Code Playgroud)


Cod*_*ker 6

这是我为防止测试休眠所做的事情:

如果我有一个在我想要测试的函数中mymodule.py导入和使用的模块:sleep

from time import sleep

def some_func()
    sleep(5)
    # ...do some things
Run Code Online (Sandbox Code Playgroud)

然后,我从正在使用它的模块中导入 sleep 进行测试,如下所示:

@mock.patch('mymodule.sleep')
def test_some_func(mock_sleep):
    mock_sleep.return_value = None
    # ...continue my test
Run Code Online (Sandbox Code Playgroud)