You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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中)

问题

请问为何会出现该错误?


问题原因与解决方法

原因分析

  1. rootdir识别错误:pytest错误地将内层django_pytest目录(包含settings.py的目录)当成了rootdir,而非外层的django-pytest目录(包含django_pytest和tests的目录),导致路径解析混乱。
  2. 模块导入路径不匹配:测试代码中使用django_pytest.library.models导入,但tests目录和django_pytest目录同级,并非嵌套关系,Python无法识别django_pytest.tests这个模块路径。
  3. pythonpath配置冗余:pythonpath = . library tests在错误的rootdir下无法正确映射到实际模块位置,反而导致路径冲突。

解决方法

  1. 修正执行路径与pytest.ini配置

    • 切换到外层django-pytest目录执行测试命令;
    • 修改pytest.ini为:
      [pytest]
      pythonpath = .
      DJANGO_SETTINGS_MODULE = django_pytest.settings
      python_files = test_*.py
      

    (.已包含当前目录下的所有模块,无需额外添加library和tests)

  2. 调整测试代码导入语句
    将测试代码中的导入改为:

    from library.models import Book
    

    直接从应用模块导入,避免依赖项目根模块的嵌套路径。

  3. 规范项目结构
    遵循Django标准结构,将测试文件移至应用内部(即library/tests目录),并确保每个tests目录下有__init__.py文件,这样Django和pytest会自动识别测试模块,无需额外配置路径。


内容的提问来源于stack exchange,提问作者JulienS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 11:18:12