Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用默认和非托管数据库运行Django单元测试?_Python_Django_Django Unittest - Fatal编程技术网

Python 如何使用默认和非托管数据库运行Django单元测试?

Python 如何使用默认和非托管数据库运行Django单元测试?,python,django,django-unittest,Python,Django,Django Unittest,我有一个Django项目,其中有一个默认数据库,用于存储用户、订单等内容 我们还有一个非托管数据库。现在,当您运行Django测试时,他们会尝试创建测试数据库,但由于我们有一个非托管数据库,所以我们无法这样做。我无法创建此数据库的迁移,因为这将导致300个关于冲突反向访问器的错误 我们使用Docker并自动启动这个非托管数据库,并用一些模拟数据填充它。这个是用于开发之类的。我希望单元测试使用这个进行测试 我尝试过创建迁移之类的事情,但由于反向访问器问题,这是不可能的 有没有办法使用非托管数据库进

我有一个Django项目,其中有一个默认数据库,用于存储用户、订单等内容

我们还有一个非托管数据库。现在,当您运行Django测试时,他们会尝试创建测试数据库,但由于我们有一个非托管数据库,所以我们无法这样做。我无法创建此数据库的迁移,因为这将导致300个关于冲突反向访问器的错误

我们使用Docker并自动启动这个非托管数据库,并用一些模拟数据填充它。这个是用于开发之类的。我希望单元测试使用这个进行测试

我尝试过创建迁移之类的事情,但由于反向访问器问题,这是不可能的


有没有办法使用非托管数据库进行单元测试?Django创建的test_默认数据库很好,但我无法创建test_非托管数据库。

我们在同一数据库中使用托管表和非托管表的设置,这可能也适用于您的用例:

我们有一个脚本从两个转储生成测试数据库:test_structure.sql和test_fixtures.sql。前者包含特定时间点的数据库结构,包括所有非托管表。后者包含测试期间非托管表中可能需要的任何数据,以及django_migrations表的内容。我们使用从{table}到标准输出的复制选择*的生成列表转储test_fixtures.sql;语句,例如:使用NULL'-NULL-';将SELECT*从obs_00.django_迁移复制到标准输出

psql-c{copy_statement}的输出使用如下函数转换为INSERT语句:

def csv2sqlinsert(table_name, data):
    """
    Convert TSV output of  COPY (SELECT * FROM {table}) TO STDOUT
    to                     INSERT INTO {table} VALUES (), ()...();
    """

    def is_int(val):
        try:
            return "{}".format(int(val)) == val
        except ValueError:
            return False

    def column(data):
        if data == "--null--":
            return "null"
        elif is_int(data):
            return data
        else:
            return "'{}'".format(data.replace("'", "''"))  # escape quotes

    rows = [row.split("\t") for row in data.decode().split("\n") if len(row) > 1]

    if len(rows) == 0:
        return f"-- no data for {table_name}\n"

    data = ",\n".join("({})".format(",".join(column(col) for col in row)) for row in rows)

    ret = ""
    ret += f"-- {table_name} ({len(rows)} rows)\n"
    ret += f"INSERT INTO {table_name} VALUES\n{data};\n"

    return ret
dropdb django_test_db
createdb django_test_db
psql -d django_test_db -f test_structure.sql
psql -d django_test_db < test_fixtures.sql
实际上,此函数更为复杂,还简化了postgis几何图形,并截断了大型文本字段以节省空间

创建测试数据库 在设置_test.py中定义测试数据库名称:

使用上述两个文件,重新创建测试数据库如下所示:

def csv2sqlinsert(table_name, data):
    """
    Convert TSV output of  COPY (SELECT * FROM {table}) TO STDOUT
    to                     INSERT INTO {table} VALUES (), ()...();
    """

    def is_int(val):
        try:
            return "{}".format(int(val)) == val
        except ValueError:
            return False

    def column(data):
        if data == "--null--":
            return "null"
        elif is_int(data):
            return data
        else:
            return "'{}'".format(data.replace("'", "''"))  # escape quotes

    rows = [row.split("\t") for row in data.decode().split("\n") if len(row) > 1]

    if len(rows) == 0:
        return f"-- no data for {table_name}\n"

    data = ",\n".join("({})".format(",".join(column(col) for col in row)) for row in rows)

    ret = ""
    ret += f"-- {table_name} ({len(rows)} rows)\n"
    ret += f"INSERT INTO {table_name} VALUES\n{data};\n"

    return ret
dropdb django_test_db
createdb django_test_db
psql -d django_test_db -f test_structure.sql
psql -d django_test_db < test_fixtures.sql
运行测试 现在我们可以使用./manage.py test-settings=settings\u test运行测试。因为在每次测试运行时重新创建数据库可能需要相当长的时间,添加-keepdb将节省您等待测试数据库还原过程的大量时间

我们对manage.py进行了如下修改,因此我们不能忘记:

#!/usr/bin/env python
import os
import sys

if __name__ == "__main__":
    if len(sys.argv) > 1 and sys.argv[1] == "test":
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings_test")
        cmd = sys.argv + ["--keepdb"]
    else:
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
        cmd = sys.argv

    from django.core.management import execute_from_command_line
    execute_from_command_line(cmd)

你试过pytest吗?它支持在测试时访问数据库。您可以使用pytest访问非托管数据库