Найти - Пользователи
Полная версия: TestCase и time.sleep
Начало » Python для экспертов » TestCase и time.sleep
1 2 3 4
Naota
Как можно эмулировать работу времени для тестов?
Андрей Светлов
monkey patch на time.sleep
Главное, в tearDown не забудьте обратно вернуть.
Naota
Тогда нужен патч всех библиотек, использующих время. Смысл не обнулить time.sleep, а передвинуть им время, не затрачивая это самое время. Может стоит подумать над сменой системного времени вручную. Какие ещё варианты могут быть?
Андрей Светлов
Вынести все использование времени в отдельную, вашу собственную библиотеку. Патчить ее.
Если же ваши библиотеки не вами писаны - то мокеры должны встраиваться перед ними.

Без конкретных примеров помочь не могу, извините.
ziro
А действительно ли Вам нужно передвигать время? Может достаточно в тесте переписать зависящие от времени данные между шагами UseCase'а, например если они хранятся в БД? Я такое в тестах часто использую, например при тестировании протухания ссылки активации пользователя на сайте.
Naota
Пишу биллинг и использую datetime.now и в тестах time.sleep. Получается, в тестах надо написать свой sleep, который бы увеличивал время для datetime.now. Самое очевидное использовать свою библиотеку, где всё и править если идут тесты.
ziro
Не уверен насчет библиотеки - достаточно простого модуля с применением условного импорта, например все запихиваем в модуль timeutils.py следующего содержания:

if config.TESTING:
# Эти функции у нас используются при тестировании
from datetime import datetime as _datetime, timedelta as _timedelta
current_time = None

def now():
"""
Mock для подмены стандартной функции datetime.now
"""
global current_time
if current_time is None:
current_time = _datetime.now()
return current_time

def sleep(seconds):
"""
Mock для подмены стандартной функции time.sleep
"""
global current_time
current_time += _timedelta(seconds=secons)

else:
# Это используется в реальной работе
from time import sleep
from datetime import datetime as _datetime
now = _datetime.now
Но чесно говоря не тестил.

PS: манкипатчинг не люблю.
Naota
Мне нужно тестировать компоненты, которые внутри используют datetime.now
Андрей Светлов
Еще один забавный трюк, который часто помогает.
import datetime

class A(object):
now = datetime.datetime.now

def __init__(self):
pass

def f(self):
return self.now() + datetime.timedelta(minutes=2)

#### Test
import unittest
import mocker

class TestA(unittest.TestCase):
def setUp(self):
self.mocker = mocker.Mocker()

def tearDown(self):
self.mocker = None

def test_something(self):
a = A()
now = self.mocker.mock()
a.now = now

current_time = datetime.datetime(2011, 2, 9, 11, 28, 33)
expected = datetime.datetime(2011, 2, 9, 11, 30, 33) # 2 mins later
now()
self.mocker.result(current_time)

with self.mocker:
ret = a.f()
self.assertEqual(expected, ret)


unittest.main()
Naota
В тестах now нет, вот пример:
        self.assertEqual(billing.can_show(), True)
time.sleep(4)
self.assertEqual(billing.can_show(), True)
time.sleep(4)
self.assertEqual(billing.can_show(), False)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB