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

运行pytest遇ModuleNotFoundError,主程序报相对导入越界错误

问题描述

项目文件结构:

.(root)
├── __init__.py
├── tests/
│   ├── __init__.py
│   └── animation_tests/
│       ├── __init__.py
│       └── test_other_animations.py
└── src/
    ├── __init__.py
    ├── alien_onslaught.py
    ├── animations/
    │   ├── __init__.py
    │   └── other_animations.py
    └── utils/
        ├── __init__.py
        └── animation_constants.py

场景1:使用绝对导入from utils.animation_constants import ...

在test_other_animations.py中导入:

from src.animations.other_animations import DestroyAnim, MissileEx, Immune

运行pytest时触发错误:

ImportError while importing test module 'C:\Users\Rux\Desktop\Programming\Projects\AlienOnslaught\alien_onslaught\tests\animation_tests\test_other_animations.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
C:\Users\Rux\AppData\Local\Programs\Python\Python311\Lib\importlib\__init__.py:126: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test_other_animations.py:7: in <module>
from src.animations.other_animations import DestroyAnim, MissileEx, Immune
> ..\..\src\animations\other_animations.py:10: in <module>
from utils.animation_constants import (
E   ModuleNotFoundError: No module named 'utils'

场景2:使用相对导入from ..utils.animation_constants import ...

修改other_animations.py的导入后,测试可正常运行,但启动主程序alien_onslaught.py时出错:

Traceback (most recent call last):
  File "C:\Users\Rux\Desktop\Programming\Projects\AlienOnslaught\Alien-Onslaught-main\src\alien_onslaught.py", line 21, in <module>
    from game_logic.collision_detection import CollisionManager
  File "C:\Users\Rux\Desktop\Programming\Projects\AlienOnslaught\Alien-Onslaught-main\src\game_logic\collision_detection.py", line 8, in <module>
    from entities.projectiles import Missile
  File "C:\Users\Rux\Desktop\Programming\Projects\AlienOnslaught\Alien-Onslaught-main\src\entities\projectiles.py", line 16, in <module>
    from animations.other_animations import MissileEx
  File "C:\Users\Rux\Desktop\Programming\Projects\AlienOnslaught\Alien-Onslaught-main\src\animations\other_animations.py", line 10, in <module>
    from ..utils.animation_constants import (
ImportError: attempted relative import beyond top-level package

核心矛盾:测试和主程序的导入逻辑无法兼容,绝对/相对导入均不能同时满足两种场景。

解决方案

方法1:统一用src开头的绝对导入,确保项目根目录在Python路径中

  1. 修改other_animations.py的导入语句:
from src.utils.animation_constants import (
    destroy_frames,
    missile_ex_frames,
    alien_immune_frames,
)
  1. 运行测试:
    • 直接在项目根目录执行pytest命令;
    • 或者先把根目录加入PYTHONPATH:
      Windows:set PYTHONPATH=C:\Users\Rux\Desktop\Programming\Projects\AlienOnslaught\alien_onslaught
      Linux/macOS:export PYTHONPATH=/path/to/your/project/root
      再执行pytest。
  2. 启动主程序:从项目根目录运行python src/alien_onslaught.py。

方法2:配置pytest自动识别根目录

在项目根目录创建pytest.ini文件,内容如下:

[pytest]
pythonpath = .

这样pytest会自动把根目录加入Python路径,此时用src开头的绝对导入,测试和主程序(从根目录启动)都能正常运行。

方法3:给主程序添加路径适配逻辑

修改alien_onslaught.py的入口部分:

if __name__ == "__main__":
    import sys
    from pathlib import Path
    # 把项目根目录添加到Python路径
    project_root = Path(__file__).parent.parent
    sys.path.append(str(project_root))
    # 后续导入和主程序逻辑
    from game_logic.collision_detection import CollisionManager
    # ...其他代码

配合src开头的绝对导入,无论从哪个路径启动主程序,都能正确找到模块,测试也能正常运行。

方法4:用模块方式启动主程序

保持other_animations.py的相对导入不变,从项目根目录用-m参数启动主程序:

python -m src.alien_onslaught

这种方式下Python会把根目录视为包的父目录,相对导入不会报错,测试也能正常运行(因为测试从根目录导入src模块,包内相对导入有效)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 00:00:23