Django(鼻子)测试加速,reuse_db无法正常工作

时间:2013-06-13 09:32:13

标签: django unit-testing django-nose

我正在使用django-nose在django(1.4)中运行我的单元测试。

TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'

创建数据库需要很长时间。

所以我发现把它放在settings.py中:

os.environ['REUSE_DB'] = "1"

应该这样做。

实际上django itsellve给出了这个建议:

To reuse old database "<path not very interesting>/var/sqlite/unittest.db" for speed, set env var REUSE_DB=1.

当然,您需要使用此标志= 0

运行一次(或在每次数据库更改后)

但是,当您将标志设置为0时,我的测试以注释结束:

Destroying test database for alias 'default'...

所以,当我想用​​重复运行它时......没有什么可以重用...而且我会得到错误,说该表不存在

DatabaseError: no such table: <and than a table name>

将reuse_db设置为0

时,测试运行完美

我在开发设置中使用测试数据库别名:

DATABASES = {
    'default': {
        'NAME': os.path.join(BUILDOUT_DIR, 'var', 'sqlite', 'development.db'),
        'TEST_NAME': os.path.join(BUILDOUT_DIR, 'var', 'sqlite', 'unittest.db'),
        'ENGINE': 'django.db.backends.sqlite3', 
        'USER': '',
        'PASSWORD': '',
        'HOST': '', 
        'PORT': '', 
        }
    }

我没有使用内存中的sqllite数据库进行测试,因为我在某处读到了django-nose不能正常工作。

那么如何在数据库最终破坏数据库时重用数据库......

根据这个https://docs.djangoproject.com/en/1.4/topics/testing/#the-test-database django正在这样做,但它没有说明如何防止这种情况(如果我可以),或者如何使用reuse_db选项。 我应该使用其他设置吗?

3 个答案:

答案 0 :(得分:9)

如果我理解正确,你不知道如何第一次创建测试数据库(为了以后重用它)。

即使您设置了REUSE_DB = 0,如果DB不存在,NoseTestSuiteRunner也应自动创建它。 如果要手动创建测试DB,可以创建以下文件:

test_db_settings.py

您指定:

from settings import *

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        # TestRunner uses a database with name that consists
        # of prefix test_ and your database name if your database
        # name is db then the test database name has to be test_db
        'NAME': 'test_db', 
        'USER': 'postgres_user',
        'PASSWORD': 'postgres_user',
        'HOST': 'localhost',
        'PORT': '5432',
        }
}

之后创建test_db:

createdb -U postgres_user -h localhost test_db # if you use postgres

python manage.py syncdb --settings test_db_settings.py
python manage.py migrate --settings test_db_settings.py (only if you use South)

现在我们有了TestRunner使用的DB。我们可以进行测试:

REUSE_DB=1 python manage.py test

更新

您确定使用NoseTestSuiteRunner吗?以下是来自django_nose.NoseTestSuiteRunner的一些代码。我们可以看到是否设置了选项REUSE_DB,然后禁用了teardown_database。如果你想要你可以调试它,例如在这里设置一个断点来检查你真的使用它的Runner等。

def teardown_databases(self, *args, **kwargs):
    """Leave those poor, reusable databases alone if REUSE_DB is true."""
    if not _reusing_db():
        return super(NoseTestSuiteRunner, self).teardown_databases(
                *args, **kwargs)
    # else skip tearing down the DB so we can reuse it next time

答案 1 :(得分:2)

我接受了安德烈·凯戈罗多夫的回答,因为他引导我找到了解决方案...读到他的回答我想(多么容易,多么愚蠢......)

无论如何,将此settings_test_db.py放在具有此内容的设置旁边: (填写项目名称)

from <myproject>.settings import *

DATABASES = {
    'default': {
        'NAME': os.path.join(BUILDOUT_DIR, 'var', 'sqlite', 'unittest.db'),
        'ENGINE': 'django.db.backends.sqlite3', 
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
        }
}

对于sqlite,您不必创建数据库。 跑吧

python manage.py syncdb --settings <myproject>.settings_test_db  

(注意:使用projectname,不使用.py)

并运行迁移

python manage.py migrate --settings <myproject>.settings_test_db

(仅当你使用南方时)

并设置 在您的settings.py中:

os.environ['REUSE_DB'] = "1" 

所以你可以使用

python manage.py test

答案 2 :(得分:1)

顺便说一句,而不是使用单独的测试设置文件... 您可以在相同的设置中定义测试题材:

DATABASES = {
    'default': {
        'NAME': os.path.join(BUILDOUT_DIR, 'var', 'sqlite', 'test.db'),
        'TEST_NAME': os.path.join(BUILDOUT_DIR, 'var', 'sqlite', 'unittest.db'),
        'ENGINE': 'django.db.backends.sqlite3', 
        'USER': '',
        'PASSWORD': '',
        'HOST': '',  # empty string for localhost.
        'PORT': '',  # empty string for default.
        }
    }