【问题标题】:Unable to connect to postgres database from django while running pytest运行pytest时无法从django连接到postgres数据库
【发布时间】:2021-02-18 22:25:32
【问题描述】:

Django 项目和 postgres 位于不同的 docker 容器中。

我想使用 pytest 为这个应用程序编写单元测试用例。

我已经使用APIClient()@pytest.mark.django_db 实现了测试用例。但是,当从本地 django 应用程序执行 pytest 时,无法访问数据库,因为它存在于不同的容器中。

我还尝试创建一个包含测试用例的新映像,登录到该容器并尝试执行 pytest。但是,它显示django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

建议我们如何建立连接以在这种情况下从 django 托管 postgres 数据库,因为 pytest 不会在 django 容器内运行。

注意:代码覆盖率也是我们的一个标准,所以不能使用 requests 模块来访问 Django REST API。

使用@pytest.mark.django_db:

platform win32 -- Python 3.8.2, pytest-6.1.1, py-1.9.0, pluggy-0.13.1 -- c:\users\schitted\appdata\local\programs\python\python38-32\python.exe
cachedir: .pytest_cache
django: settings: app.settings (from ini)
metadata: {'Python': '3.8.2', 'Platform': 'Windows-10-10.0.18362-SP0', 'Packages': {'pytest': '6.1.1', 'py': '1.9.0', 'pluggy': '0.13.1'}, 'Plugins': {'assert-utils': '0.2.1', 'common-subject': '1.0.4', 'cov': '2.10.1', 'djang
o': '4.1.0', 'drf': '1.1.0', 'fixture-order': '0.1.3', 'html': '2.1.1', 'lambda': '1.2.0', 'metadata': '1.10.0'}}
rootdir: C:\code\cc_cat_unittest_git\cat-eob-service\app, configfile: pytest.ini
plugins: assert-utils-0.2.1, common-subject-1.0.4, cov-2.10.1, django-4.1.0, drf-1.1.0, fixture-order-0.1.3, html-2.1.1, lambda-1.2.0, metadata-1.10.0
collected 1 item                                                                                                                                                                                                                 

test/test_django.py::test_unauthorized_request ERROR

============================================================================================================ ERRORS =============================================================================================================
__________________________________________________________________________________________ ERROR at setup of test_unauthorized_request __________________________________________________________________________________________

request = <SubRequest '_django_db_marker' for <Function test_unauthorized_request>>

    @pytest.fixture(autouse=True)
    def _django_db_marker(request):
        """Implement the django_db marker, internal to pytest-django.

        This will dynamically request the ``db``, ``transactional_db`` or
        ``django_db_reset_sequences`` fixtures as required by the django_db marker.
        """
        marker = request.node.get_closest_marker("django_db")
        if marker:
            transaction, reset_sequences = validate_django_db(marker)
            if reset_sequences:
                request.getfixturevalue("django_db_reset_sequences")
            elif transaction:
                request.getfixturevalue("transactional_db")
            else:
>               request.getfixturevalue("db")

c:\users\schitted\appdata\local\programs\python\python38-32\lib\site-packages\pytest_django\plugin.py:436:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
c:\users\schitted\appdata\local\programs\python\python38-32\lib\site-packages\pytest_django\fixtures.py:105: in django_db_setup
    db_cfg = setup_databases(
c:\users\schitted\appdata\local\programs\python\python38-32\lib\site-packages\django\test\utils.py:157: in setup_databases
    test_databases, mirrored_aliases = get_unique_databases_and_mirrors(aliases)
c:\users\schitted\appdata\local\programs\python\python38-32\lib\site-packages\django\test\utils.py:258: in get_unique_databases_and_mirrors
    default_sig = connections[DEFAULT_DB_ALIAS].creation.test_db_signature()
c:\users\schitted\appdata\local\programs\python\python38-32\lib\site-packages\django\db\backends\base\creation.py:303: in test_db_signature
    self._get_test_db_name(),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <django.db.backends.postgresql.creation.DatabaseCreation object at 0x0423ED60>

    def _get_test_db_name(self):
        """
        Internal implementation - return the name of the test DB that will be
        created. Only useful when called from create_test_db() and
        _create_test_db() and when no external munging is done with the 'NAME'
        settings.
        """
        if self.connection.settings_dict['TEST']['NAME']:
            return self.connection.settings_dict['TEST']['NAME']
>       return TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME']
E       TypeError: can only concatenate str (not "NoneType") to str

c:\users\schitted\appdata\local\programs\python\python38-32\lib\site-packages\django\db\backends\base\creation.py:161: TypeError
==================================================================================================== short test summary info ====================================================================================================
ERROR test/test_django.py::test_unauthorized_request - TypeError: can only concatenate str (not "NoneType") to str
======================================================================================================= 1 error in 19.76s =======================================================================================================```

【问题讨论】:

  • 这不是关于测试,而是关于连接两个容器。阅读有关 docker 网络和端口发布的信息。完成后,使用正确的数据库地址更新 django 的测试设置。
  • 我能够连接 django、postgres 容器并能够访问 API。但是,当我尝试从本地执行测试用例时,我遇到了连接数据库的问题。

标签: python-3.x postgresql docker django-rest-framework pytest


【解决方案1】:

检查设置文件中给出的 postgres 主机。确保它已连接到数据库容器。通常,给出容器名称而不是主机上的 IP

【讨论】:

  • 设置文件已经包含连接数据库所需的信息。我能够运行 django 服务器并访问 API。但是当我触发测试用例时,我收到了上面提到的以下错误。
猜你喜欢
  • 2017-11-12
  • 2020-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-11
  • 2011-08-31
  • 2017-09-13
  • 2016-07-31
相关资源
最近更新 更多