Django 1.5 Timezone.now()

时间:2013-08-10 08:15:16

标签: django unit-testing datetime django-models django-timezone

我是新手,并试图让我的单元测试通过,但遇到DateTimeField问题。

在我的设置中,我设置了USE_TZ = True和TIME_ZONE。

使用MongoDb。

首先,测试给我一个错误,抱怨比较offset-naive和offset-aware。将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 个答案:

答案 0 :(得分:3)

问题在于您要比较两个不同时间点分配的时间'现在'的两个值。

由于时间的不断变化,在尝试断言确切的日期值时,编写单元测试以使用自动生成的日期总是很棘手。但是,有几种技术可用于帮助在这些场景中创建可靠的测试:

  • 如果你试图断言“nfse_no_banco.data_emissao包含现在的时间”,而不是试图断言一个确切的值,你可以断言时间字段值落在最后x毫秒的时间内。这使您可以获得相当高的置信度,即该字段中的值在分配时是“现在”,但缺点是(a)如果测试的执行时间花费的时间超过,则您的测试可能不可靠x毫秒和(b)如果由于某种原因由于编程错误(非常不可能)而错误地将值分配给非常接近的时间,则测试将返回误报。

  • 您可以将datetime.datetime.utcnow猴子补丁到您自己的方法版本,该方法返回用于测试目的的预设值,然后断言该值已分配给nfse_no_banco.data_emissao。缺点是它会增加您的测试设置和拆卸的复杂性。但是,如果断言的目标是验证字段已经分配了时间,那么它应该会得到一个很好的测试。

  • 您可以简单地声明该字段的值不为null(使用self.assertNotNull(nfse_no_banco.data_emissao)) - 尽管这是一个弱得多的断言,在您使用某些框架功能的情况下(例如{{然后通常这就足够了 - 当然这个测试的主要优点是它非常简单和可靠。

最好的方法实际上取决于你试图断言的内容。从你的问题来看,你似乎真的试图断言auto_now_add=True现在被赋予了时间,而你自己就是这样做的(而不是依靠框架为你做这件事),因此第二种方法就是最有意义的。

下面是伪代码,展示了如何在测试中执行此操作:

nfse_no_banco.data_emissao
相关问题