Django测试用例数据库给出不一致的响应,缓存或事务元凶? [英] Django test case db giving inconsistent responses, caching or transaction culprit?

查看:97
本文介绍了Django测试用例数据库给出不一致的响应,缓存或事务元凶?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到Django测试确实有些令人惊讶和令人沮丧的行为。正在通过相关查找找到模型对象,但是不存在模型对象。 (我对这里的怪异描述表示歉意……这种行为非常奇怪,以至于我不知道如何描述它。这些对象是否存在?我是否存在?您吗?)

I am seeing some really surprising and frustrating behavior with Django testing. Model objects are being "found" by a related lookup, but no model objects exist. (I apologize for the weird description here...the behavior is bizarre enough that I don't know quite how to describe it. Do the objects exist? Do I exist? Do you??)

我需要它们存在,所以我有一个适当的方法可以在它们不存在时创建它们。问题在于,在一行中,Django发现它们确实存在,因此没有创建它们……然后在下一行中,我们可以确认不存在此类对象。

I need them to exist, so I have a method in place that creates them if they don't exist. The problem is that on one line, Django finds that they do exist, and therefore they are not created...and then on the next line we can confirm that no such objects exist.

我的测试正在给出test_something()错误,该错误与缺少必需的TaskMetadata对象有关。

My tests are giving Errors in test_something() related to the absence of the necessary TaskMetadata object.

#the model
class TaskMetadata(models.Model):
    task = models.OneToOneField(ContentType)
    ...

#the test
class SimpleTest(TestCase):
    def setUp(self):
        some_utility_function()

    def test_something(self):
        ...something that requires TaskMetadata...

def some_utility_function():
    task = ...whatever...
    ctype = ContentType.objects.get_for_model(task)
    try:
        ctype.taskmetadata
    except TaskMetadata.DoesNotExist:
        ...create TaskMetadata...
        print "Created TaskMetadata object for %s" % task.__name__
    else:
        print "TaskMetadata object already exists for %s" % task.__name__
        print ctype.taskmetadata
        print "ALL OF THEM!! %s" % TaskMetadata.objects.all()

和some_utility_function()的打印结果:

and the printed result of some_utility_function():

TaskMetadata object already exists for SomeTask
some task
ALL OF THEM!! []     # <-- NOTE EMPTY QUERYSET

总而言之:是的,TaskMetadata对象存在。是的,TaskMetadata对象存在。不,根本没有TaskMetadata对象!

In summary: "Yes, TaskMetadata object exists. Yes, TaskMetadata object exists. No, there are no TaskMetadata objects at all!!"

所以,说真的,这到底是怎么回事?这是缓存问题吗?我尝试清除缓存(很奇怪;我在settings.py中没有配置缓存)

So, seriously, what on earth is going on here? Is this a cache problem? I tried clearing the cache (wild guess; I don't have CACHES configured in settings.py)

def setUp(self):
    cache.clear()
    some_utility_function()

没有帮助。

更新:
看一个最小的django项目,它复制了问题此处

当第一个测试用例运行时,TaskMetadata.objects .all()不是一个空的查询集(实际上,正如我所期望的那样,它填充有对象);当第二个测试用例(与第一个完全相同)运行时,它是空的。

When the first testcase runs, TaskMetadata.objects.all() is NOT an empty queryset (it is in fact populated with objects, as I would expect); when the second testcase (exactly the same as the first) runs, it is empty.

我怀疑这与清除用例TaskMetadata对象,b的测试用例之间的数据库刷新有关由于相关的查询已被缓存,因此,下次为下一个测试用例调用some_utility_function()时,它不会创建任何TaskMetadata对象。 1)合理吗? 2)如何解决? 3)这是Django错误,对吧?

I suspect this has something to do with database flushing between testcases that is clearing out the TaskMetadata objects, but the related lookup is cached, and so the next time some_utility_function() is called for the next testcase, it doesn't create any TaskMetadata objects. 1) Is that plausible? 2) How to work around it? 3) This is a Django bug, right?

Django错误凭单

推荐答案

在您的 tearDown 中您需要调用 ContentType .objects.clear_cache()。这是因为Django缓存了 ContentType.objects.get_for_model 的调用。拥有一对一的内容类型有点奇怪,所以我认为django不需要为此做任何更改,特别是因为它应该是您的一站式解决方案。

In your tearDown method you need to call ContentType.objects.clear_cache(). This is because Django caches calls to ContentType.objects.get_for_model. Having a one-to-one to content type is a bit weird, so I don't think django needs to make any changes for this, especially as it should be a one line fix for you.

这篇关于Django测试用例数据库给出不一致的响应,缓存或事务元凶?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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