【发布时间】: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