Django:在单独的线程中使用相同的测试数据库 [英] Django: using same test database in a separate thread

查看:192
本文介绍了Django:在单独的线程中使用相同的测试数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用具有以下数据库设置的测试数据库运行pytests。

I am running pytests using a test database with the following DB settings.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'postgres',
        'USER': 'something',
        'PASSWORD': 'password',

    },
}

使用@ pytest.mark.django_db,我的测试函数访问为测试创建的名为test_postgres的数据库。

Using the @pytest.mark.django_db, my test functions access a database called 'test_postgres' created for the tests.

@pytest.mark.django_db
def test_example():
    from django.db import connection
    cur_ = connection.cursor()
    print cur_.db.settings_dict

输出:

{'ENGINE': 'django.db.backends.postgresql_psycopg2', 'AUTOCOMMIT': True, 'ATOMIC_REQUESTS': False, 'NAME': 'test_postgres', 'TEST_MIRROR': None,...

但我f我在test_example内运行一个线程:

but if I run a thread inside test_example:

def function_to_run():
    from django.db import connection
    cur_ = connection.cursor
    logger.error(cur_.db.settings_dict)

@pytest.mark.django_db
def test_example():
    p = multiprocessing.Process(target=function_to_run)
    p.start()

我可以看到线程游标正在使用名为postgres的数据库,这是非测试数据库。输出:

I can see that in that thread the cursor is using database named 'postgres' which is the non-testing database. Output:

{'ENGINE': 'django.db.backends.postgresql_psycopg2', 'AUTOCOMMIT': True, 'ATOMIC_REQUESTS': False, 'NAME': 'postgres', 'TEST_MIRROR': None,...

是有一种方式可以从原始测试函数传递一个数据库连接参数到我的线程,并告诉我的线程程序使用相同的数据库名称('test_postgres')作为我的测试函数?

Is there a way to pass a database connection argument to my thread from the original test function and tell my thread routine to use the same database name ('test_postgres') as my test function?

推荐答案

我找到了解决问题的方法。

I found a workaround to my problem.

首先你准备一个单独的Django设置文件进行测试(settings_pytest.py ),使用以下DATABASES设置:

First you prepare a separate Django settings file for testing (settings_pytest.py), with the following DATABASES setting:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'test_database',
        'TEST_NAME': 'test_database',
        'USER': 'something',
        'PASSWORD': 'password',

    },
}

请注意,我们定义TEST_NAME,它与NAME相同,因此,通过测试运行器或不运行,我们将访问相同的数据库。

Notice that we define TEST_NAME, and it's the same as NAME, so that running through test runner or not, we will be accessing same database.

现在,您需要创建此数据库,并在其上运行syncdb和迁移首先:

Now you need to create this database, and run 'syncdb' and 'migrate' on it first:

sql> CREATE DATABASE test_database;

manage.py syncdb --settings=settings_pytest

manage.py migrate --settings=settings_pytest

最后,您可以运行以下测试:

Finally you can run your tests with:

py.test --reuse-db

您需要指定--reuse-db,数据库重新创建将永远不会工作,因为默认数据库与测试数据库相同。如果您的数据库有更改,您将需要使用上述命令手动重新创建数据库。

You need to specify --reuse-db, database re-creation will never work since the default database is the same as the test database. If there are changes to your database you will need to recreate the database manually with the commands above.

对于测试本身,如果要向数据库添加记录,您需要被生成的子进程访问,请记住向pytest装饰器添加transaction = True。

For the test itself, if you are adding records to the database that you need to be accessed by the spawned child process, remember to add transaction=True to the pytest decorator.

def function_to_run():

    Model.objects.count() == 1

@pytest.mark.django_db(transaction=True)
def test_example():
    obj_ = Model()
    obj_.save()
    p = multiprocessing.Process(target=function_to_run)
    p.start()

这篇关于Django:在单独的线程中使用相同的测试数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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