django对象id在单元测试之间递增

时间:2011-06-06 09:22:49

标签: python django unit-testing django-testing

我在Debian上使用Django 1.2.3-3 + squeeze1使用PostgreSQL 8.4.7-0squeeze2(尽管我认为PostgreSQL与此无关),并使用以下setUp运行基于unittest的Django单元测试和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 + "/*")

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

无论如何,如果有人可以推荐数据库,我会采取干净的方式来删除数据库。这个方法可能会进入test2Testing Django applications提到了以下功能,但我无法从teadDown导入它。令人困惑的是,这个功能似乎在django.test.utils中。

  

destroy_test_db(old_database_name,verbosity = 1)

     

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

这句话的第一部分是Ok - “销毁数据库,其名称存储在DATABASES的NAME中”, 但是“设置NAME使用提供的名称”是什么意思?我假设提供的名称是django/db/backends/creation.py

目前尚不清楚上下文中old_database_name是什么。它是NAME中的NAME,如果是, 为什么我需要设置已设置的内容? 我假设提供的名称是DATABASES,  但如果是这样,为什么我要将其设置为名为old_database_name的参数? 这句话在开发文档中没有变化。

编辑:

在Steve Mayne的回复(见下文)之后,我想我会详细说明这一点的背景。

此应用程序最初是在2007/2008/2009编写的,包括单元测试。在大部分时间里,我使用的是1.0版本的Django。根据{{​​3}},1.0于2008年9月3日发布。所描述的设置在此期间运行良好。我看到上面的tearDown函数最初写于2007年12月。那么,也许Django的行为发生了变化?

事后看来,我意识到清空表,就像上面old_database_name所做的那样,并不能保证id计数会重置为tearDown,因为序列可以是表中的单独对象

感谢史蒂夫的解决方案。如果它存在,我想听听序列重置的便携式解决方案。我也对如何使1函数起作用的解释感兴趣。

1 个答案:

答案 0 :(得分:5)

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

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

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