不同的数据库在Django中进行测试?

时间:2011-01-10 19:13:46

标签: django unit-testing sqlite postgresql

DATABASES = {
#    'default': {
#        'ENGINE': 'postgresql_psycopg2',
#        ...
#    }

    # for unit tests
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'mydatabase'
    }
}

我有两个数据库:一个我想用于单元测试,一个用于其他一切。是否可以在Django 1.2.4中配置它?

(我问的原因是因为使用postgresql我收到以下错误:

foo@bar:~/path/$ python manage.py test
Creating test database 'default'...
Got an error creating the test database: permission denied to create database

Type 'yes' if you would like to try deleting the test database 'test_baz', or 'no' to cancel: yes
Destroying old test database...
Got an error recreating the test database: database "test_baz" does not exist

为什么我会收到此错误?我想我真的不在乎我是否总能使用SQLite进行单元测试,因为它可以正常工作。)

9 个答案:

答案 0 :(得分:64)

settings.py(或local_settings.py)中:

import sys
if 'test' in sys.argv:
    DATABASES['default'] = {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'mydatabase'
    }

答案 1 :(得分:31)

我处理这个问题的方法是通过拥有多个设置文件,因为我使用它来维护一组包含每个实例修改的常用设置。设置比其他一些解决方案稍微复杂一点,但我还是需要这样做,因为我正在为本地开发,远程开发,升级和生产管理略有不同的设置。

https://code.djangoproject.com/wiki/SplitSettings有许多用于管理设置的选项,我选择的做法与https://code.djangoproject.com/wiki/SplitSettings#SimplePackageOrganizationforEnvironments

中描述的做法类似

所以,在我的Django项目目录中,我有一个如下所示的设置文件夹:

$ tree settings
settings
├── defaults.py
├── dev.py
├── dev.pyc
├── __init__.py
├── lettuce.py
├── travis.py
├── unittest.py

常见设置在settings / defaults.py中,我在实例设置文件中导入这些设置。所以settings / unittest.py看起来像这样:

from defaults import *

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'my_database',
    }
} 

然后,当我想运行测试时,我只执行:

$ ./manage.py test --settings=settings.unittest

使用sqlite进行测试。如果我想使用不同的测试运行器或数据库配置,我将使用不同的设置模块。

答案 2 :(得分:12)

想提一下,您可以在settings.py中指定测试数据库。看到 https://docs.djangoproject.com/en/2.0/ref/settings/#test

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'USER': 'mydatabaseuser',
        'NAME': 'mydatabase',
        'TEST': {
            'NAME': 'mytestdatabase',
        },
    },
}

答案 3 :(得分:6)

这大大加快了测试的执行速度。

import sys

if 'test' in sys.argv:
    DATABASES['default'] = {
        'ENGINE': 'django.db.backends.sqlite3',
        'TEST_CHARSET': 'UTF8', # if your normal db is utf8
        'NAME': ':memory:', # in memory
        'TEST_NAME': ':memory:', # in memory
    }

    DEBUG = False # might accelerate a bit
    TEMPLATE_DEBUG = False

    from django.core.management import call_command
    call_command('syncdb', migrate=True) # tables don't get created automatically for me

答案 4 :(得分:3)

如果您有权手动创建数据库,则可以使用django-nose作为TEST_RUNNER。安装后,如果传递以下环境变量,则不会删除并重新创建数据库。

REUSE_DB=1 ./manage.py test

您还可以将以下内容添加到settings.py中,这样每次要运行测试时都不必编写REUSE_DB = 1:

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

注意:这也将使您的所有表格都保留在数据库中,这意味着测试设置会更快一点,但您必须手动更新表格(或更改模型时,请自行删除并重新创建数据库。

答案 5 :(得分:3)

虽然这已经解决了......

如果您的测试数据库只是一个普通的数据库:

我认为你没有进行单元测试,因为你依赖于数据库。无论如何,django包含一个测试类型(不是单一的):django.test.TestCase

您需要从django.test.TestCase而不是unittest.TestCase派生,这将为您创建一个新的rehershal数据库,在测试结束时将被销毁。

在以下链接中有关于使用db进行测试的有趣解释/提示
Testing Django Applications

答案 6 :(得分:1)

  

为什么我会收到此错误?

由于权限不足。在使用超级用户权限运行ALTER USER username CREATEDB;后,您可以psql更改用户权限。

实施例,

$ sudo su - postgres
$ psql
psql (9.3.18)
Type "help" for help.

postgres=# ALTER USER username CREATEDB;
ALTER ROLE

答案 7 :(得分:1)

我解决了这个问题,只需创建其他设置常量DATABASES_AVAILABLE

DATABASES_AVAILABLE = {
    'main': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'nep',
        'USER': 'user',
        'PASSWORD': 'passwd',
        'HOST': 'localhost',
    },
    'remote': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'nes_dev',
        'USER': 'usr',
        'PASSWORD': 'passwd',
        'HOST': '200.144.254.136',
    },
    'sqlite': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
}

# This solves the problem with tests
# Define a system variable called DJANGO_DATABASE_TEST and set it to the
# the database you want
database = os.environ.get('DJANGO_DATABASE_TEST', 'main')
DATABASES = {
    'default': DATABASES_AVAILABLE[database]
}

答案 8 :(得分:1)

您可以通过编辑 settings.py 来镜像您的数据库:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'USER': 'mydatabaseuser',
        'NAME': 'mydatabase',
        'TEST': {
            'MIRROR': 'default',
        },
    },
}