使用pytest-django测试Django应用时遇ModuleNotFoundError求助
Django单元测试ModuleNotFoundError问题排查
背景说明
我正在学习Django单元测试,搭建了一个极简应用。
问题描述
启动Django应用单元测试时,明明模块存在,却抛出ModuleNotFoundError。
相关代码与配置
视图代码
from django.shortcuts import get_object_or_404, render from .models import Book def book_infos(request, pk): book = get_object_or_404(Book, pk=pk) return render(request, "book_infos.html", {'book': book})
测试代码
import pytest from django.urls import reverse from django.test import Client from django_pytest.library.models import Book from pytest_django.asserts import assertTemplateUsed @pytest.mark.django_db def test_book_infos_view(): client = Client() Book.objects.create(author="Jules Verne", title="20 milles lieues sous les mers") path = reverse('infos', kwargs={'pk': 1}) response = client.get(path) content = response.content.decode() expected_content = "<p>Jules Verne | 20 milles lieues sous les mers</p>" assert content == expected_content assert response.status_code == 200 assertTemplateUsed(response, "book_infos.html")
pytest.ini配置
[pytest] pythonpath = . library tests DJANGO_SETTINGS_MODULE = django_pytest.settings python_files = test_*.py
运行命令与错误信息
从django-pytest目录执行命令:
pytest tests/library/test_views.py
得到错误结果:
platform win32 -- Python 3.11.5, pytest-7.4.3, pluggy-1.3.0 django: version: 4.2.7, settings: django_pytest.settings (from ini) rootdir: ...\django-pytest\django_pytest configfile: pytest.ini plugins: django-4.6.0 _ ERROR collecting tests/library/test_views.py _ ImportError while importing test module '...\django-pytest\django_pytest\tests\library\test_views.py'. Hint: make sure your test modules/packages have valid Python names. Traceback: C:\Python311\Lib\importlib\__init__.py:126: in import_module return _bootstrap._gcd_import(name[level:], package, level) E ModuleNotFoundError: No module named 'django_pytest.tests'
调试时的错误信息:
ERROR: not found: ...\django-pytest\django_pytest\tests\library\test_views.py::test_book_infos_view (no name '...\\django-pytest\\django_pytest\\tests\\library\\test_views.py::test_book_infos_view' in any of [<Module test_views.py>]) tests/library/test_views.py:None (tests/library/test_views.py) ImportError while importing test module '...\django-pytest\django_pytest\tests\library\test_views.py'. Hint: make sure your test modules/packages have valid Python names. Traceback: ..\..\..\venv\Lib\site-packages\_pytest\python.py:617: in _importtestmodule mod = import_path(self.path, mode=importmode, root=self.config.rootpath) ..\..\..\venv\Lib\site-packages\_pytest\pathlib.py:567: in import_path importlib.import_module(module_name) C:\Python311\Lib\importlib\__init__.py:126: in import_module return _bootstrap._gcd_import(name[level:], package, level) E ModuleNotFoundError: No module named 'django_pytest.tests'
已尝试的解决方法
- 检查pytest与pytest-django的兼容性;
- 在pytest.ini中添加
pythonpath = . library tests; - 从django-pytest目录执行
py -m pytest,但出现配置错误:ERROR django_pytest/tests/library/test_views.py - django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessin...; - 尝试调整项目结构,将测试文件移至library模块内。
技术栈
Python==3.11 Django==4.2.7 pytest==7.4.3 pytest-django==4.6.0
(所有包均安装在虚拟环境venv中)
问题
请问为何会出现该错误?
问题原因与解决方法
原因分析
- rootdir识别错误:pytest错误地将内层
django_pytest目录(包含settings.py的目录)当成了rootdir,而非外层的django-pytest目录(包含django_pytest和tests的目录),导致路径解析混乱。 - 模块导入路径不匹配:测试代码中使用
django_pytest.library.models导入,但tests目录和django_pytest目录同级,并非嵌套关系,Python无法识别django_pytest.tests这个模块路径。 - pythonpath配置冗余:
pythonpath = . library tests在错误的rootdir下无法正确映射到实际模块位置,反而导致路径冲突。
解决方法
修正执行路径与pytest.ini配置
- 切换到外层
django-pytest目录执行测试命令; - 修改
pytest.ini为:[pytest] pythonpath = . DJANGO_SETTINGS_MODULE = django_pytest.settings python_files = test_*.py
(
.已包含当前目录下的所有模块,无需额外添加library和tests)- 切换到外层
调整测试代码导入语句
将测试代码中的导入改为:from library.models import Book直接从应用模块导入,避免依赖项目根模块的嵌套路径。
规范项目结构
遵循Django标准结构,将测试文件移至应用内部(即library/tests目录),并确保每个tests目录下有__init__.py文件,这样Django和pytest会自动识别测试模块,无需额外配置路径。
内容的提问来源于stack exchange,提问作者JulienS
相关产品推荐
相关产品推荐

