Django 1.5 Timezone.now()
Я новичок и пытаюсь выполнить мой модульный тест, но у меня проблемы с DateTimeField.
В моих настройках у меня USE_TZ = True и TIME_ZONE.
Использование MongoDb.
Во-первых, тест дает мне ошибку с жалобами на сравнение смещений наивно и с учетом смещений. Изменено auto_now_add=True для datetime.datetime.utcnow(). Replace(tzinfo=utc))
Я все еще не мог получить правильное время и дату для своего TIME_ZONE.
После того, как я положил их в свою базу данных (settings.py)
'OPTIONS' : {
'tz_aware' : True,
}
Теперь я могу изменить TIME_ZONE, а время и дата показывают мое местное время, а не utc.
Но когда я запускаю тестовую модель:
nf.data_emissao = timezone.now()
...
#check if the nf is in database
lista_nfse = Nfse.objects.all()
self.assertEquals(lista_nfse.count(), 1)
nfse_no_banco = lista_nfse[0]
...
self.assertEquals( nfse_no_banco.data_emissao, nf.data_emissao)
Мой тест не пройден:
AssertionError: datetime.datetime(2013, 8, 10, 2, 49, 59, 391000, tzinfo=
<bson.tz_util.FixedOffset object at 0x2bdd1d0>) != datetime.datetime(2013, 8, 10, 2, 49, 59,
391122, tzinfo=<UTC>)
Я вижу разницу между 391000 и 391122, но не знаю, как это исправить.
1 ответ
Проблема в том, что вы сравниваете два значения, которые были назначены со временем "сейчас" в два разных момента времени.
Написание модульных тестов для работы с автоматически сгенерированными датами всегда сложно при попытке установить точные значения даты из-за постоянно меняющейся природы времени. Однако есть несколько методов, которые можно использовать для создания надежных тестов в этих сценариях:
Если вы пытаетесь утверждать
nfse_no_banco.data_emissao
содержит время сейчас ', вместо того чтобы пытаться установить точное значение, вы можете утверждать, что значение поля времени находится в пределах последних x миллисекунд времени. Это позволяет вам получить достаточную уверенность в том, что значение в поле было "сейчас" во время его назначения, но есть и недостатки: (а) ваш тест может быть ненадежным, если время выполнения теста занимает больше времени, чем x миллисекунд и (b) тест выдаст ложное срабатывание, если по какой-то причине значение было неправильно назначено на очень близкое время из-за ошибки программирования (что весьма маловероятно).Вы можете обезьяна-патч
datetime.datetime.utcnow
к вашей собственной версии метода, которая возвращает заданное значение для целей тестирования, а затем утверждает, что значение было присвоеноnfse_no_banco.data_emissao
, Недостатком является то, что это немного усложняет настройку и разбор тестов. Тем не менее, это должно привести к хорошей проверке, если цель вашего утверждения состоит в том, чтобы убедиться, что поле было назначено время.Вы можете просто утверждать, что значение поля не равно нулю (используя
self.assertNotNull(nfse_no_banco.data_emissao)
) - хотя это гораздо более слабое утверждение, в тех случаях, когда вы используете некоторые функциональные возможности платформы (например,auto_now_add=True
в Джанго), то часто этого будет достаточно - конечно, главный плюс этого теста - он очень прост и надежен.
Лучший подход действительно зависит от того, что вы пытаетесь отстаивать. Из вашего вопроса видно, что вы действительно пытаетесь утверждать, что nfse_no_banco.data_emissao
было назначено время сейчас, и вы делаете это самостоятельно (вместо того, чтобы полагаться на структуру, которая сделает это за вас), и поэтому второй подход будет наиболее целесообразным.
Ниже приведен псевдокод, показывающий, как вы можете сделать это в своем тесте:
# Create a constant with a fixed value for utcnow
NOW = datetime.datetime.utcnow()
# Define a test method to replace datetime.datetime.utcnow
def utcnow_fixed_value():
return NOW
class MyTest(TestCase):
def setUp(self):
# Replace the real version of utcnow with our test version
self.real_utcnow = datetime.datetime.utcnow
datetime.datetime.utcnow = utcnow_fixed_value
def tearDown(self):
# Undo the monkey patch and replace the real version of utcnow
datetime.datetime.utcnow = self.real_utcnow
def test_value_is_now(self):
lista_nfse = Nfse.objects.all()
self.assertEquals(lista_nfse.count(), 1)
nfse_no_banco = lista_nfse[0]
...
self.assertEquals(NOW, nfse_no_banco.data_emissao)