django对象在单元测试之间增加 [英] django object ids increment between unit tests

查看:164
本文介绍了django对象在单元测试之间增加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Django 1.2.3-3 + squeeze1在Debian上用PostgreSQL 8.4.7-0squeeze2压缩(尽管我不认为PostgreSQL在这里是相关的),并且运行基于unittest的Django单元测试与以下setUp和$ d

  def setUp(self):
打印运行安装程序
self.c =客户端()
self.user = User.objects.create_user('faheem','faheem@email.unc.edu','foo')
self.logged_in = self.c.login(username = 'faheem',password ='foo')
settings.MEDIA_ROOT ='/ tmp /'
#settings.ZIP_UPLOAD ='/ var / tmp / zip /'

def tearDown(self):
printrunning teardown
FolderUpload.objects.all()。delete()
FileUpload.objects.all()。delete()
ZipFileUpload。 objects.all()。delete()
OldFileUpload.objects.all()。delete()
#FIXME:Quick&肮脏的修复,暂时。应该做一个删除方法。
os.system(rm -rf+ settings.ZIP_UPLOAD +/ *)

想法是在运行单元测试之间从数据库中删除所有内容。根据单元测试文档,
tearDown 所用的。我所遇到的问题是,在不同的单元测试之间,似乎仍然存在一些状态。
具体来说,我看到ids增加了。所以让我们说如果我在 test1 中创建一个 ZipFileUpload 对象,然后创建一个 ZipFileUpload 对象在 test2 中,那么我会期望两个id都是 1 ,但是我看到是 1 c test1 和id 2 TEST2 。如果ids来自某些生活在这些表之外的索引,这将是有意义的。我不知道Diango如何做到这一点,知道事实上是这样的。如果他们这样做,我不知道为什么。任何澄清这一点将不胜感激。



无论如何,如果有人可以建议一个,我会建议一个干净的方式删除数据库。这个方法应该进入 teadDown 测试Django应用程序提到以下功能,但是我未能从 django.test.utils 。令人困惑的是,这个函数似乎在 django / db / backends / creation.py 中。


destroy_test_db(old_database_name,verbosity = 1)



销毁名称为存储在DATABASES中的NAME中,并将NAME设置为使用提供的名称。


这句话的第一部分是Ok - 在DATABASES中销毁名称存储在NAME中的数据库,
,但是将NAME设置为使用提供的名称是什么意思?我假设提供的名称是 old_database_name



目前还不清楚什么是 NAME 是在上下文中。是否在 DATABASES 中的 NAME ,如果是,
为什么我需要设置一些已经设置好了
我假设提供的名称是 old_database_name
但是如果是这样,为什么要将其设置为一个称为 old_database_name
这个句子在开发文档中没有变化。



编辑:



Steve Mayne的回复(见下文),我以为我会详细说明一下这个背景。



这个应用程序最初是写在2007/2008/2009,包括单元测试。在大部分时间里,我都在使用1.0版的Django。根据 Ken Cochran的Django发行历史,1.0发布于2008年9月3日。在这段时间里描述的设置正常。我看到上面的tearDown功能最初是在2007年12月写的。那么Django的行为可能会改变吗?



事后看来,我意识到,将表排空,如$ $ c> tearDown 在上面,不保证id计数将重置为 1 ,因为序列可以是一个单独的对象表。



感谢Steve为他的解决方案。如果存在,我想听听有关序列重置的便携式解决方案。我也有兴趣解释如何使 destroy_test_db 函数在上面工作。

解决方案

您可以使用以下SQL重置每个表上的ID序列:

  SELECT pg_catalog.setval pg_get_serial_sequence('table_name','id'),1); 

如果你的表是空的,你应该这样做。


I'm using Django 1.2.3-3+squeeze1 on Debian squeeze with PostgreSQL 8.4.7-0squeeze2 (though I don't think PostgreSQL is relevant here), and running Django unit tests based on unittest with the following setUp and tearDown

   def setUp(self):
        print "running setup"
        self.c = Client()
        self.user = User.objects.create_user('faheem', 'faheem@email.unc.edu', 'foo')
        self.logged_in = self.c.login(username='faheem', password='foo')
        settings.MEDIA_ROOT='/tmp/'
        #settings.ZIP_UPLOAD='/var/tmp/zip/'

    def tearDown(self):
        print "running teardown"
        FolderUpload.objects.all().delete()
        FileUpload.objects.all().delete()
        ZipFileUpload.objects.all().delete()
        OldFileUpload.objects.all().delete()
        # FIXME: Quick & dirty fix for the time being. Should make this a delete method.
        os.system("rm -rf "+ settings.ZIP_UPLOAD + "/*")

The idea is for everything to be removed from the database between running unit tests. According to the unittest documentation, that is what tearDown is for. The problem I am having is that there still seems to be some state saved between the different unit tests. Specifically, I'm seeing that the ids get incremented. So lets say if I create one ZipFileUpload object in test1, and then create one ZipFileUpload object in test2, then I would expect both ids to be 1, but what I see is that is id 1 for test1 and id 2 fortest2. This would make sense if the ids come from some index which lives outside these tables. I don't know enough about how Diango does this to know if that is in fact the case. If they are doing it this way, I have no idea why. Any clarification on this point would be appreciated.

Regardless, I would settle for a clean way to drop the database, if anyone can suggest one. This method should probably go into teadDown. Testing Django applications mentions the following function, but I failed to import it from django.test.utils. Confusingly, this function seems to be in django/db/backends/creation.py.

destroy_test_db(old_database_name, verbosity=1)

Destroys the database whose name is in stored in NAME in the DATABASES, and sets NAME to use the provided name.

The first part of this sentence is Ok - "Destroy the database whose name is stored in NAME in the DATABASES", but what is meant by "sets NAME to use the provided name" mean? I assume the provided name is old_database_name,

It is not clear what NAME is in the context. Is it the NAME in DATABASES, and if so, why do I need to set something that is already set? I assume the provided name is old_database_name, but if so, why would I want to set it to an argument called old_database_name? This sentence is unchanged in development docs.

EDIT:

After a reply from Steve Mayne (see below), I thought I would elaborate on the background of this a little bit.

This application was originally written over 2007/2008/2009, including the unit tests. During most of that time, I was using pre 1.0 releases of Django. According to Ken Cochran's Django Release History, 1.0 was released on September 3rd, 2008. The setup described worked fine during that time. I see that the tearDown function above was originally written in December 2007. So, perhaps Django's behavior changed?

In hindsight, I realise that emptying the tables, as tearDown does above, does not guarantee that the id count will be reset to 1, since the sequence can be a separate object from the table.

Thanks to Steve for his solution. If it exists, I'd like to hear about a portable solution to the sequence reset. I'd also be interested in an explanation of how to make the destroy_test_db function above work.

解决方案

You can reset the ID sequence on each table using the following SQL:

SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), 1);

You should only do this if your table is empty.

这篇关于django对象在单元测试之间增加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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