Docker 容器中的 Django 单元测试:ModuleNotFoundError:没有名为“code.x”的模块;“代码”不是一个包

Sil*_*ver 3 python testing django unit-testing docker

这是我使用 Django 的第一个项目,也是我第一次使用 Docker。到目前为止,我真的很喜欢它们,但我面临一个一周后无法解决的问题。

\n

我按照本教程构建我的项目:https://medium.com/swlh/setting-up-a-secure-django-project-repository-with-docker-and-django-environ-4af72ce037f0

\n

到目前为止,我的项目结构如下所示:

\n
MyProject\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 backend                  # Django "app"\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 admin.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 apps.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 models.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 permissions.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 serializers.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 tests.py\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 views.py   \n\xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 config                  # Django "project"\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 asgi.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 settings.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 urls.py\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 wsgi.py \n\xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 docker                  # Docker configuration files, content close to the source link above\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ... \n\xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 frontend                # independent angular project\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ...        \n\xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py    <====== # The file responsible of all the trouble !\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 .gitignore   \n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 manage.py\n
Run Code Online (Sandbox Code Playgroud)\n

我的项目在容器内正常启动并运行,一切都按预期工作。\n好吧,几乎一切..

\n

我编写了一些简单的测试,并尝试从“web”容器(包含 Web 应用程序)内部运行它们\n每当我运行时,python manage.py test我都会收到以下错误:

\n
root@web:/code# python manage.py test\nSystem check identified no issues (0 silenced).\nEE\n======================================================================\nERROR: code.backend (unittest.loader._FailedTest)\n----------------------------------------------------------------------\nImportError: Failed to import test module: code.backend\nTraceback (most recent call last):\n  File "/usr/local/lib/python3.9/unittest/loader.py", line 470, in _find_test_path\n    package = self._get_module_from_name(name)\n  File "/usr/local/lib/python3.9/unittest/loader.py", line 377, in _get_module_from_name\n    __import__(name)\nModuleNotFoundError: No module named \'code.backend\'; \'code\' is not a package\n\n\n======================================================================\nERROR: code.config (unittest.loader._FailedTest)\n----------------------------------------------------------------------\nImportError: Failed to import test module: code.config\nTraceback (most recent call last):\n  File "/usr/local/lib/python3.9/unittest/loader.py", line 470, in _find_test_path\n    package = self._get_module_from_name(name)\n  File "/usr/local/lib/python3.9/unittest/loader.py", line 377, in _get_module_from_name\n    __import__(name)\nModuleNotFoundError: No module named \'code.config\'; \'code\' is not a package\n\n\n----------------------------------------------------------------------\nRan 2 tests in 0.000s\n\nFAILED (errors=2)\nUsing selector: EpollSelector\n
Run Code Online (Sandbox Code Playgroud)\n

即使使用完全空的tests.py文件,我也会收到上述错误。

\n

我对 Django 和 python 项目结构的理解非常基本,从我发现的情况来看,它与错误的导入有关,可以通过使用相对导入来修复,如下所述:十亿次相对导入

\n

我从不手动导入code为包或模块,因为它是 Web 容器内项目的父目录。为什么测试尝试导入它?为什么只有测试才会导致此错误?

\n

我想这与我的项目的结构和 Django 设置的定义方式有关,但我承认我完全迷失了并且有点绝望,因为我真的对 Django 和 Docker 都不熟悉。

\n

请随意询问任何特定的文件内容,并提前感谢您的阅读和尝试提供帮助!

\n
\n

编辑:按照下面的要求,这是我的测试文件,docker-compose 和 Dockerfile。

\n

测试.py:

\n
from django.test import TestCase\nfrom backend.models import User\n\nclass UserTestCase(TestCase) :\n    # Setups \n    def create_user(self, email="user@email", username="username", name="name", isActive="true", isSuperUser="false", password="pass"):\n        return User.objects.create(email=email, username=username, name=name, isActive=isActive, isSuperUser=isSuperUser, password=password)\n\n    # Models tests\n    def test_create_user(self):\n        user = self.create_user()\n        self.assertIsInstance(user, User)\n
Run Code Online (Sandbox Code Playgroud)\n

我应该提到,即使使用空的测试文件,我也会遇到上述错误。

\n
\n

Dockerfile:

\n
# Pull a base image\nFROM python:3.9-slim-buster\n\n# Set environment variables\nENV PYTHONDONTWRITEBYTECODE 1\nENV PYTHONUNBUFFERED 1\n\n# Create a working directory for the django project\nWORKDIR /django\n\n# Install dependencies\nCOPY requirements.txt /django/\nRUN pip install -r requirements.txt\n\n# Copy the project files into the working directory\nCOPY . /django/\nWORKDIR /code\n\n# Open a port on the container\nEXPOSE 8000\n
Run Code Online (Sandbox Code Playgroud)\n
\n

docker-compose(删除了一些不相关的内容):

\n
version: \'3.9\'\nservices:\n  db:\n    ...\n  web:\n    build:\n      context: ./web\n    command: ["./docker/wait-for-it.sh", "db:5432", "--timeout=30", "--strict", "--", "python", "/code/manage.py", "runserver", "0.0.0.0:8000"]\n    volumes:\n      - ../:/code\n    restart: always\n    depends_on:\n        - db\n  front:\n    ...\n\n
Run Code Online (Sandbox Code Playgroud)\n

Sil*_*ver 7

回答我自己的问题,因为我终于找到了我所有麻烦的原因......

我在项目的根目录创建了一个__init__.py文件,将项目版本定义为常量。

在阅读了有关 Django 模块和命名空间的内容后,我__init__.py从根目录中删除了它们,这解决了问题。

**编辑上面的问题以显示有问题的文件