pytest-django 的 setup_databases 包装错误

Wrapped error with setup_databases for pytest-django

在我向我的模型添加新的 class 之后,我无法 运行 在我的服务器中进行测试。问题是错误消息似乎被包装并且没有提供有关错误的更多信息。如您所见,数据库中不存在 table,正如预期的那样,但为什么我无法检索到更多信息,为什么它无法 "setup_databases"?

我正在使用 SQLITE 执行这些测试。应该创建一个文件并应用迁移。我可以 运行 它在我的电脑上没有问题,但在服务器上我不能。它只是在下面的堆栈中失败了。

我的挣扎现在持续了将近 3 天,我不知道我能做些什么来解决这个问题。

注意事项: 我使用 factory boyGitLab,如您所见,pytest-django.

coverage_report.sh

/bin/py.test --cov=. --cov-report=term-missing --no-cov-on-fail --cov-fail-under=90 v3 api web

测试设置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ATOMIC_REQUESTS': True,
    }
}

pytest.ini

[pytest]
DJANGO_SETTINGS_MODULE=v3.settings_testing
markers =
    integration
    unittest
    selenium

test_classes.py

class CustomerReputationFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.CustomerReputation

    customer = factory.SubFactory(CustomerFactory)
    reputation = factory.SubFactory(ReputationFactory)
    assignment_reason = "Reason for tag assignment"

class ReputationFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.Reputation

    tag_name = factory.Sequence(lambda n: "reputation-tag-%d" % n)
    description = "I am a reputation tag"
    warning_level = 'CW'
    disabled = False

class TestAddCustomerReputation:
    @pytest.fixture
    def prerequisites(self, db):
        customer = factories.CustomerFactory()
        customer_reputation = factories.CustomerReputationFactory.create_batch(3)
        reputations = factories.ReputationFactory.create_batch(3)
        return {
            'customer': customer,
            'reputations': reputations,
            'customer_reputation': customer_reputation
        }

    @pytest.mark.integration
    def test_can_add_reputation(self, prerequisites, db):
        customer_reputation = prerequisites['customer_reputation']
        customer = prerequisites['customer']
        reputations = prerequisites['reputations']

        customer_reputation[0].customer = customer
        customer_reputation[0].reputation = reputations[0]
        customer_reputation[0].assignment_description = "Bad customer"
        customer_reputation[0].save()

        assert reputations[0] in customer.reputation.all()
        assert reputations[1] not in customer.reputation.all()

堆栈的一部分

只是一部分,因为有点大。所有需要数据库访问的测试都失败了。

$ ./coverage_report.sh ./env
============================= test session starts ==============================
platform linux -- Python 3.4.3, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
django settings: v3.settings_testing (from ini file)
rootdir: /home/gitlab_ci_multi_runner/builds/3e679c18/0/company-staff/project, inifile: pytest.ini
plugins: django-2.9.1, cov-2.3.0, mock-1.1, xdist-1.14
collected 565 items

v3/tests/test_flattened_proxy_models.py EEEEEEEEE
v3/tests/test_managers.py EEEEEEEE
v3/tests/test_services.py EEEEEEEEEEEEEE.EEEEEEE
v3/tests/test_zendesk.py ................
api/tests/test_api.py EEE
api/tests/test_filters.py ..EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
api/tests/test_viewsets.py EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
web/tests/test_accounts.py EEEEEEEEEEEEE
web/tests/test_addresses.py EEEEEEEE
web/tests/test_agreements.py EEEEEEEEEEEEEE
web/tests/test_calc_vat.py EEEE
web/tests/test_check_vat.py ......
web/tests/test_collection_utils.py ...
web/tests/test_config.py EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
web/tests/test_contacts.py EEEEEEE
web/tests/test_custom_invoice_lines.py EEEE
web/tests/test_customers.py EEEEEEEEEEEEEEEEEEEEEE
web/tests/test_files.py EEEEEEEEEEEEEEE
web/tests/test_forms.py EEEEEEEEEEEEEEEEEEEEE
web/tests/test_initial_data.py EE
web/tests/test_invoices.py EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.EEEEEEEEEEEEEEEEEEEEEEEEEE
web/tests/test_license_import.py EEEEE
web/tests/test_login.py .EEEE
web/tests/test_markdown_template.py .E
web/tests/test_models.py EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
web/tests/test_payments.py EEEEEEEEEEEEEEEEEEEEE
web/tests/test_product.py EEEEEE
web/tests/test_profile.py EEE
web/tests/test_querysets.py EEEE
web/tests/test_report.py EEEEEEEEEEEEEEEEEEEEEEE
web/tests/test_shipping.py EEE
web/tests/test_tasks.py EEEEEEEEE
web/tests/test_todo.py EEEEEEEEEEEEEEEEEEEEE

==================================== ERRORS ====================================
___ ERROR at setup of TestFlattenedProxyModel.test_original_must_be_provided ___

request = <SubRequest '_django_db_setup' for <Function 'test_original_must_be_provided'>>
_django_test_environment = None
_django_cursor_wrapper = <pytest_django.plugin.CursorManager object at 0x7f670846bcf8>

    @pytest.fixture(scope='session')
    def _django_db_setup(request,
                         _django_test_environment,
                         _django_cursor_wrapper):
        """Session-wide database setup, internal to pytest-django"""
        skip_if_no_django()

        from .compat import setup_databases, teardown_databases

        # xdist
        if hasattr(request.config, 'slaveinput'):
            db_suffix = request.config.slaveinput['slaveid']
        else:
            db_suffix = None

        monkey_patch_creation_for_db_suffix(db_suffix)

        _handle_south()

        if request.config.getvalue('nomigrations'):
            _disable_native_migrations()

        with _django_cursor_wrapper:
            # Monkey patch Django's setup code to support database re-use
            if request.config.getvalue('reuse_db'):
                if not request.config.getvalue('create_db'):
                    monkey_patch_creation_for_db_reuse()

            # Create the database
            db_cfg = setup_databases(verbosity=pytest.config.option.verbose,
>                                    interactive=False)

env/lib/python3.4/site-packages/pytest_django/fixtures.py:54: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
env/lib/python3.4/site-packages/django/test/runner.py:370: in setup_databases
    serialize=connection.settings_dict.get("TEST", {}).get("SERIALIZE", True),
env/lib/python3.4/site-packages/django/db/backends/base/creation.py:376: in create_test_db
    self.connection._test_serialized_contents = self.serialize_db_to_string()
env/lib/python3.4/site-packages/django/db/backends/base/creation.py:413: in serialize_db_to_string
    serializers.serialize("json", get_objects(), indent=None, stream=out)
env/lib/python3.4/site-packages/django/core/serializers/__init__.py:129: in serialize
    s.serialize(queryset, **options)
env/lib/python3.4/site-packages/django/core/serializers/base.py:52: in serialize
    for obj in queryset:
env/lib/python3.4/site-packages/django/db/backends/base/creation.py:409: in get_objects
    for obj in queryset.iterator():
env/lib/python3.4/site-packages/django/db/models/query.py:238: in iterator
    results = compiler.execute_sql()
env/lib/python3.4/site-packages/django/db/models/sql/compiler.py:840: in execute_sql
    cursor.execute(sql, params)
env/lib/python3.4/site-packages/django/db/backends/utils.py:64: in execute
    return self.cursor.execute(sql, params)
env/lib/python3.4/site-packages/django/db/utils.py:97: in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
env/lib/python3.4/site-packages/django/utils/six.py:658: in reraise
    raise value.with_traceback(tb)
env/lib/python3.4/site-packages/django/db/backends/utils.py:64: in execute
    return self.cursor.execute(sql, params)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <django.db.backends.sqlite3.base.SQLiteCursorWrapper object at 0x7f67068f8af8>
query = 'SELECT "v3_customerreputation"."id", "v3_customerreputation"."created_at", "v3_customerreputation"."updated_at", "v3_...d", "v3_customerreputation"."assignment_reason" FROM "v3_customerreputation" ORDER BY "v3_customerreputation"."id" ASC'
params = ()

    def execute(self, query, params=None):
        if params is None:
            return Database.Cursor.execute(self, query)
        query = self.convert_query(query)
>       return Database.Cursor.execute(self, query, params)
E       django.db.utils.OperationalError: no such table: v3_customerreputation

env/lib/python3.4/site-packages/django/db/backends/sqlite3/base.py:318: OperationalError
_ ERROR at setup of TestFlattenedProxyModel.test_fields_match_original_fields __

request = <SubRequest '_django_db_setup' for <Function 'test_original_must_be_provided'>>
_django_test_environment = None
_django_cursor_wrapper = <pytest_django.plugin.CursorManager object at 0x7f670846bcf8>

    @pytest.fixture(scope='session')
    def _django_db_setup(request,
                         _django_test_environment,
                         _django_cursor_wrapper):
        """Session-wide database setup, internal to pytest-django"""
        skip_if_no_django()

        from .compat import setup_databases, teardown_databases

        # xdist
        if hasattr(request.config, 'slaveinput'):
            db_suffix = request.config.slaveinput['slaveid']
        else:
            db_suffix = None

        monkey_patch_creation_for_db_suffix(db_suffix)

        _handle_south()

        if request.config.getvalue('nomigrations'):
            _disable_native_migrations()

        with _django_cursor_wrapper:
            # Monkey patch Django's setup code to support database re-use
            if request.config.getvalue('reuse_db'):
                if not request.config.getvalue('create_db'):
                    monkey_patch_creation_for_db_reuse()

            # Create the database
            db_cfg = setup_databases(verbosity=pytest.config.option.verbose,
>                                    interactive=False)

env/lib/python3.4/site-packages/pytest_django/fixtures.py:54: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
env/lib/python3.4/site-packages/django/test/runner.py:370: in setup_databases
    serialize=connection.settings_dict.get("TEST", {}).get("SERIALIZE", True),
env/lib/python3.4/site-packages/django/db/backends/base/creation.py:376: in create_test_db
    self.connection._test_serialized_contents = self.serialize_db_to_string()
env/lib/python3.4/site-packages/django/db/backends/base/creation.py:413: in serialize_db_to_string
    serializers.serialize("json", get_objects(), indent=None, stream=out)
env/lib/python3.4/site-packages/django/core/serializers/__init__.py:129: in serialize
    s.serialize(queryset, **options)
env/lib/python3.4/site-packages/django/core/serializers/base.py:52: in serialize
    for obj in queryset:
env/lib/python3.4/site-packages/django/db/backends/base/creation.py:409: in get_objects
    for obj in queryset.iterator():
env/lib/python3.4/site-packages/django/db/models/query.py:238: in iterator
    results = compiler.execute_sql()
env/lib/python3.4/site-packages/django/db/models/sql/compiler.py:840: in execute_sql
    cursor.execute(sql, params)
env/lib/python3.4/site-packages/django/db/backends/utils.py:64: in execute
    return self.cursor.execute(sql, params)
env/lib/python3.4/site-packages/django/db/utils.py:97: in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
env/lib/python3.4/site-packages/django/utils/six.py:658: in reraise
    raise value.with_traceback(tb)
env/lib/python3.4/site-packages/django/db/backends/utils.py:64: in execute
    return self.cursor.execute(sql, params)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <django.db.backends.sqlite3.base.SQLiteCursorWrapper object at 0x7f67068f8af8>
query = 'SELECT "v3_customerreputation"."id", "v3_customerreputation"."created_at", "v3_customerreputation"."updated_at", "v3_...d", "v3_customerreputation"."assignment_reason" FROM "v3_customerreputation" ORDER BY "v3_customerreputation"."id" ASC'
params = ()

    def execute(self, query, params=None):
        if params is None:
            return Database.Cursor.execute(self, query)
        query = self.convert_query(query)
>       return Database.Cursor.execute(self, query, params)
E       django.db.utils.OperationalError: no such table: v3_customerreputation

env/lib/python3.4/site-packages/django/db/backends/sqlite3/base.py:318: OperationalError
_ ERROR at setup of TestSellerInformationProxy.test_all_fields_properly_copied _

request = <SubRequest '_django_db_setup' for <Function 'test_original_must_be_provided'>>
_django_test_environment = None
_django_cursor_wrapper = <pytest_django.plugin.CursorManager object at 0x7f670846bcf8>

    @pytest.fixture(scope='session')
    def _django_db_setup(request,
                         _django_test_environment,
                         _django_cursor_wrapper):
        """Session-wide database setup, internal to pytest-django"""
        skip_if_no_django()

        from .compat import setup_databases, teardown_databases

        # xdist
        if hasattr(request.config, 'slaveinput'):
            db_suffix = request.config.slaveinput['slaveid']
        else:
            db_suffix = None

        monkey_patch_creation_for_db_suffix(db_suffix)

        _handle_south()

        if request.config.getvalue('nomigrations'):
            _disable_native_migrations()

        with _django_cursor_wrapper:
            # Monkey patch Django's setup code to support database re-use
            if request.config.getvalue('reuse_db'):
                if not request.config.getvalue('create_db'):
                    monkey_patch_creation_for_db_reuse()

            # Create the database
            db_cfg = setup_databases(verbosity=pytest.config.option.verbose,
>                                    interactive=False)

env/lib/python3.4/site-packages/pytest_django/fixtures.py:54: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
env/lib/python3.4/site-packages/django/test/runner.py:370: in setup_databases
    serialize=connection.settings_dict.get("TEST", {}).get("SERIALIZE", True),
env/lib/python3.4/site-packages/django/db/backends/base/creation.py:376: in create_test_db
    self.connection._test_serialized_contents = self.serialize_db_to_string()
env/lib/python3.4/site-packages/django/db/backends/base/creation.py:413: in serialize_db_to_string
    serializers.serialize("json", get_objects(), indent=None, stream=out)
env/lib/python3.4/site-packages/django/core/serializers/__init__.py:129: in serialize
    s.serialize(queryset, **options)
env/lib/python3.4/site-packages/django/core/serializers/base.py:52: in serialize
    for obj in queryset:
env/lib/python3.4/site-packages/django/db/backends/base/creation.py:409: in get_objects
    for obj in queryset.iterator():
env/lib/python3.4/site-packages/django/db/models/query.py:238: in iterator
    results = compiler.execute_sql()
env/lib/python3.4/site-packages/django/db/models/sql/compiler.py:840: in execute_sql
    cursor.execute(sql, params)
env/lib/python3.4/site-packages/django/db/backends/utils.py:64: in execute
    return self.cursor.execute(sql, params)
env/lib/python3.4/site-packages/django/db/utils.py:97: in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
env/lib/python3.4/site-packages/django/utils/six.py:658: in reraise
    raise value.with_traceback(tb)
env/lib/python3.4/site-packages/django/db/backends/utils.py:64: in execute
    return self.cursor.execute(sql, params)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <django.db.backends.sqlite3.base.SQLiteCursorWrapper object at 0x7f67068f8af8>
query = 'SELECT "v3_customerreputation"."id", "v3_customerreputation"."created_at", "v3_customerreputation"."updated_at", "v3_...d", "v3_customerreputation"."assignment_reason" FROM "v3_customerreputation" ORDER BY "v3_customerreputation"."id" ASC'
params = ()

    def execute(self, query, params=None):
        if params is None:
            return Database.Cursor.execute(self, query)
        query = self.convert_query(query)
>       return Database.Cursor.execute(self, query, params)
E       django.db.utils.OperationalError: no such table: v3_customerreputation

env/lib/python3.4/site-packages/django/db/backends/sqlite3/base.py:318: OperationalError
______ ERROR at setup of TestAddressProxy.test_all_fields_properly_copied ______

request = <SubRequest '_django_db_setup' for <Function 'test_original_must_be_provided'>>
_django_test_environment = None
_django_cursor_wrapper = <pytest_django.plugin.CursorManager object at 0x7f670846bcf8>

    @pytest.fixture(scope='session')
    def _django_db_setup(request,
                         _django_test_environment,
                         _django_cursor_wrapper):
        """Session-wide database setup, internal to pytest-django"""
        skip_if_no_django()

        from .compat import setup_databases, teardown_databases

        # xdist
        if hasattr(request.config, 'slaveinput'):
            db_suffix = request.config.slaveinput['slaveid']
        else:
            db_suffix = None

        monkey_patch_creation_for_db_suffix(db_suffix)

        _handle_south()

        if request.config.getvalue('nomigrations'):
            _disable_native_migrations()

        with _django_cursor_wrapper:
            # Monkey patch Django's setup code to support database re-use
            if request.config.getvalue('reuse_db'):
                if not request.config.getvalue('create_db'):
                    monkey_patch_creation_for_db_reuse()

            # Create the database
            db_cfg = setup_databases(verbosity=pytest.config.option.verbose,
>                                    interactive=False)

env/lib/python3.4/site-packages/pytest_django/fixtures.py:54: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
env/lib/python3.4/site-packages/django/test/runner.py:370: in setup_databases
    serialize=connection.settings_dict.get("TEST", {}).get("SERIALIZE", True),
env/lib/python3.4/site-packages/django/db/backends/base/creation.py:376: in create_test_db
    self.connection._test_serialized_contents = self.serialize_db_to_string()
env/lib/python3.4/site-packages/django/db/backends/base/creation.py:413: in serialize_db_to_string
    serializers.serialize("json", get_objects(), indent=None, stream=out)
env/lib/python3.4/site-packages/django/core/serializers/__init__.py:129: in serialize
    s.serialize(queryset, **options)
env/lib/python3.4/site-packages/django/core/serializers/base.py:52: in serialize
    for obj in queryset:
env/lib/python3.4/site-packages/django/db/backends/base/creation.py:409: in get_objects
    for obj in queryset.iterator():
env/lib/python3.4/site-packages/django/db/models/query.py:238: in iterator
    results = compiler.execute_sql()
env/lib/python3.4/site-packages/django/db/models/sql/compiler.py:840: in execute_sql
    cursor.execute(sql, params)
env/lib/python3.4/site-packages/django/db/backends/utils.py:64: in execute
    return self.cursor.execute(sql, params)
env/lib/python3.4/site-packages/django/db/utils.py:97: in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
env/lib/python3.4/site-packages/django/utils/six.py:658: in reraise
    raise value.with_traceback(tb)
env/lib/python3.4/site-packages/django/db/backends/utils.py:64: in execute
    return self.cursor.execute(sql, params)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <django.db.backends.sqlite3.base.SQLiteCursorWrapper object at 0x7f67068f8af8>
query = 'SELECT "v3_customerreputation"."id", "v3_customerreputation"."created_at", "v3_customerreputation"."updated_at", "v3_...d", "v3_customerreputation"."assignment_reason" FROM "v3_customerreputation" ORDER BY "v3_customerreputation"."id" ASC'
params = ()

    def execute(self, query, params=None):
        if params is None:
            return Database.Cursor.execute(self, query)
        query = self.convert_query(query)
>       return Database.Cursor.execute(self, query, params)
E       django.db.utils.OperationalError: no such table: v3_customerreputation

env/lib/python3.4/site-packages/django/db/backends/sqlite3/base.py:318: OperationalError
______ ERROR at setup of TestContactProxy.test_all_fields_properly_copied ______

request = <SubRequest '_django_db_setup' for <Function 'test_original_must_be_provided'>>
_django_test_environment = None
_django_cursor_wrapper = <pytest_django.plugin.CursorManager object at 0x7f670846bcf8>

    @pytest.fixture(scope='session')
    def _django_db_setup(request,
                         _django_test_environment,
                         _django_cursor_wrapper):
        """Session-wide database setup, internal to pytest-django"""
        skip_if_no_django()

        from .compat import setup_databases, teardown_databases

        # xdist
        if hasattr(request.config, 'slaveinput'):
            db_suffix = request.config.slaveinput['slaveid']
        else:
            db_suffix = None

        monkey_patch_creation_for_db_suffix(db_suffix)

        _handle_south()

        if request.config.getvalue('nomigrations'):
            _disable_native_migrations()

        with _django_cursor_wrapper:
            # Monkey patch Django's setup code to support database re-use
            if request.config.getvalue('reuse_db'):
                if not request.config.getvalue('create_db'):
                    monkey_patch_creation_for_db_reuse()

            # Create the database
            db_cfg = setup_databases(verbosity=pytest.config.option.verbose,
>                                    interactive=False)

好吧,几个小时后我发现我忘记将迁移提交到 GitLab。 pytest-django 不知道要迁移什么,因此出现问题。