Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 7, 2011 15:52:18

Naota
От:
Зарегистрирован: 2007-06-04
Сообщения: 197
Репутация: +  0  -
Профиль   Отправить e-mail  

TestCase и time.sleep

Как можно эмулировать работу времени для тестов?



Офлайн

#2 Фев. 7, 2011 17:42:59

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

TestCase и time.sleep

monkey patch на time.sleep
Главное, в tearDown не забудьте обратно вернуть.



Офлайн

#3 Фев. 8, 2011 10:40:02

Naota
От:
Зарегистрирован: 2007-06-04
Сообщения: 197
Репутация: +  0  -
Профиль   Отправить e-mail  

TestCase и time.sleep

Тогда нужен патч всех библиотек, использующих время. Смысл не обнулить time.sleep, а передвинуть им время, не затрачивая это самое время. Может стоит подумать над сменой системного времени вручную. Какие ещё варианты могут быть?



Офлайн

#4 Фев. 8, 2011 10:45:06

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

TestCase и time.sleep

Вынести все использование времени в отдельную, вашу собственную библиотеку. Патчить ее.
Если же ваши библиотеки не вами писаны - то мокеры должны встраиваться перед ними.

Без конкретных примеров помочь не могу, извините.



Офлайн

#5 Фев. 8, 2011 10:52:54

ziro
От:
Зарегистрирован: 2009-08-13
Сообщения: 225
Репутация: +  8  -
Профиль   Отправить e-mail  

TestCase и time.sleep

А действительно ли Вам нужно передвигать время? Может достаточно в тесте переписать зависящие от времени данные между шагами UseCase'а, например если они хранятся в БД? Я такое в тестах часто использую, например при тестировании протухания ссылки активации пользователя на сайте.



Офлайн

#6 Фев. 8, 2011 11:25:21

Naota
От:
Зарегистрирован: 2007-06-04
Сообщения: 197
Репутация: +  0  -
Профиль   Отправить e-mail  

TestCase и time.sleep

Пишу биллинг и использую datetime.now и в тестах time.sleep. Получается, в тестах надо написать свой sleep, который бы увеличивал время для datetime.now. Самое очевидное использовать свою библиотеку, где всё и править если идут тесты.



Офлайн

#7 Фев. 8, 2011 12:21:55

ziro
От:
Зарегистрирован: 2009-08-13
Сообщения: 225
Репутация: +  8  -
Профиль   Отправить e-mail  

TestCase и time.sleep

Не уверен насчет библиотеки - достаточно простого модуля с применением условного импорта, например все запихиваем в модуль 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: манкипатчинг не люблю.



Офлайн

#8 Фев. 9, 2011 11:00:14

Naota
От:
Зарегистрирован: 2007-06-04
Сообщения: 197
Репутация: +  0  -
Профиль   Отправить e-mail  

TestCase и time.sleep

Мне нужно тестировать компоненты, которые внутри используют datetime.now



Офлайн

#9 Фев. 9, 2011 11:32:35

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

TestCase и time.sleep

Еще один забавный трюк, который часто помогает.

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()



Офлайн

#10 Фев. 9, 2011 17:03:11

Naota
От:
Зарегистрирован: 2007-06-04
Сообщения: 197
Репутация: +  0  -
Профиль   Отправить e-mail  

TestCase и time.sleep

В тестах 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)



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version