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, но не знаю, как это исправить.


person yellowbuck    schedule 10.08.2013    source источник
comment
Согласно документам это должно быть USE_TZ=True. И ты тоже делал sudo pip install pytz?   -  person dan-klasson    schedule 10.08.2013
comment
Это может зависеть от конфигурации вашего компьютера. У вас где-то настроен часовой пояс? Во-вторых, разница в модульном тесте составляет 0,000122 секунды. Вероятно, время между двумя обращениями к now(). Выделите немного времени для вычислений в ваших тестах.   -  person Bouke    schedule 10.08.2013
comment
@ dan-klasson да, USE_TZ = True. Я установил pytz в virtualenv. Я видел, как он установлен, когда пип застывает. Я также поставил "pytz" в "Установленные приложения".   -  person yellowbuck    schedule 10.08.2013
comment
@bouke Я установил только свой TIME_ZONE в settings.py. Да, я думаю, что время вычислений может объяснить разницу. Я хочу пройти тест, но не могу понять, как ...   -  person yellowbuck    schedule 10.08.2013
comment
@ user227719 Я имел ввиду настройки вашего компьютера (OSX / Win / Linux). Это может привести к неправильному времени UTC. Чтобы исправить ваши модульные тесты, дайте примерно 0,1 секунды для вычислений.   -  person Bouke    schedule 10.08.2013
comment
@bouke В настройках моего компьютера (ubuntu) указан мой город. Время устанавливается автоматически из Интернета. По поводу исправления я попробую это, спасибо!   -  person yellowbuck    schedule 10.08.2013


Ответы (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 в Django), тогда часто этого будет достаточно - конечно Главный плюс этого теста в том, что он очень простой и надежный.

Лучший подход действительно зависит от того, что вы пытаетесь утверждать. Из вашего вопроса кажется, что вы действительно пытаетесь утверждать, что 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)
person robjohncox    schedule 11.08.2013