Django 1.5 Timezone.now() [英] Django 1.5 Timezone.now()

查看:153
本文介绍了Django 1.5 Timezone.now()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



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

我是新手,试图让我的单元测试通过,但是在DateTimeField出现问题。 p>

使用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如果nf在数据库
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对象在0x2bdd1d0>)!= dat etime.datetime(2013,8,10,2,49,59,
391122,tzinfo =< UTC)

我看到差异在391000和391122之间,但不知道如何解决。

解决方案

这个问题看起来是在两个不同的时间点比较分配给now的两个值。



编写单元测试自动工作由于时间不断变化的性质,尝试确定确切的日期值时,生成的日期总是棘手的。然而,有几种技术可用于帮助在这些情况下创建可靠的测试:




  • 如果您正在尝试要断言' nfse_no_banco.data_emissao 包含现在的时间',而不是试图断言一个确切的值,你可以声明时间字段值落在最后x毫秒的时间内。这允许您获得一个相当的信心,即该领域的价值在分配时是现在,但缺点是(a)如果测试的执行时间要花费更长时间,您的测试可能不可靠x毫秒,(b)如果由于某种原因,由于编程错误(这是非常不可能的),该值被错误地分配了非常接近的时间,测试将返回一个错误的肯定。


  • 您可以将$-code> datetime.datetime.utcnow 猴子修补到您自己的返回预设值的方法进行测试,然后断言该值已分配给 nfse_no_banco.data_emissao 。缺点是它增加了一些复杂的测试设置和拆卸。但是,如果您的断言的目标是验证该字段现在已经被分配了时间,那么应该会得到很好的测试。


  • 您可以简单地断言该字段的值不为空(使用 self.assertNotNull(nfse_no_banco.data_emissao)) - 尽管这是一个非常弱的断言,在您使用某个框架的情况下功能(例如,Django中的 auto_now_add = True )然后经常这将足够 - 当然这个测试的主要优势是非常简单和可靠。




最好的方法真的取决于你想要断言的内容。从你的问题看来,你真的试图断言,现在已经分配了 nfse_no_banco.data_emissao ,而你自己正在做这件事(而不是依靠一个框架来做)对于你),因此第二种方法将是最有意义的。



以下是显示您在测试中如何执行此操作的伪代码:

 #为utcnow创建一个具有固定值的常量
NOW = datetime.datetime.utcnow()

#定义一个测试方法来替换datetime.datetime.utcnow
def utcnow_fixed_value():
return NOW

class MyTest(TestCase):

def setUp(self):
#用我们的测试版本替换真实版本的utcnow
self.real_utcnow = datetime.datetime.utcnow
datetime.datetime.utcnow = utcnow_fixed_value

def tearDown(self):
#撤消猴子补丁并替换真实版本的utcnow
datetime.datetime.u tcnow = 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)


I am newbie and trying to make my Unit Test pass but having problems with DateTimeField.

In my settings, I have USE_TZ = True and TIME_ZONE set.

Using MongoDb.

First the test is giving me an error complaining about comparing offset-naive and offset-aware. Changed auto_now_add=True to datetime.datetime.utcnow().replace(tzinfo=utc))

I Still couldn't get the right time and date to my TIME_ZONE.

After I put these in my Database (settings.py)

'OPTIONS' : {
    'tz_aware' : True, 
}

Now I can change my TIME_ZONE and the time and date shows my localtime, not utc.

But when I run a test model:

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)

My test fails:

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

I see the diff between 391000 and 391122 but don't know how to fix that.

解决方案

The problem look to be that you are comparing two values that were assigned with the time 'now' at two different points in time.

Writing unit tests to work with automatically generated dates is always tricky when trying to assert exact date values due to the ever changing nature of time. However, there are a couple of techniques that can be used to help create reliable tests in these scenarios:

  • If you are trying to assert 'nfse_no_banco.data_emissao contains the time now', instead of trying to assert an exact value you could assert that the time field value falls within the last x milliseconds of time. This allows you to gain a fair level of confidence that the value in the field was 'now' at the time it was assigned, but the downsides are (a) your test could unreliable if the execution time of the test happens to take longer than x milliseconds and (b) the test would return a false positive if for some reason the value was incorrectly assigned a time very close to now due to a programming error (which is highly unlikely).

  • You can monkey-patch datetime.datetime.utcnow to your own version of the method that returns a pre-set value for testing purposes, and then assert that value was assigned to nfse_no_banco.data_emissao. The downside is that it adds a little complexity to your test setup and teardown. However, it should result in a good test if the goal of your assertion is to verify that the field has been assigned the time now.

  • You can simply assert that the value of the field is not null (using self.assertNotNull(nfse_no_banco.data_emissao)) - although this is a much weaker assertion, in cases where you are using some framework functionality (such as auto_now_add=True in Django) then often this will suffice - of course the major upside to this test is it's very simple and reliable.

The best approach really depends on what you are trying to assert. From your question it appears that you are really trying to assert that nfse_no_banco.data_emissao was assigned the time now, and you are doing this yourself (rather than relying on a framework to do it for you), and therefore the second approach would make most sense.

Below is pseudo-code showing how you could do this in your test:

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

这篇关于Django 1.5 Timezone.now()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆