使用Pytest运行测试遇ModuleNotFoundError:无法导入同目录模块s3
问题描述
在some_project项目中使用Pytest运行单元测试时,main_0.py导入同目录下的s3.py失败,抛出ModuleNotFoundError: no module named 's3'错误。
项目初始目录结构
some_project └───src ├───main │ └───lambda_function │ └───some │ main_0.py │ s3.py │ └───test └───unittest └───lambda_function └───some test_main_0.py test_s3.py
相关代码
main_0.py
from s3 import PrintS3 def lambda_handler(): obj = PrintS3() res = obj.print_txt() return res
s3.py
class PrintS3: def __init__(self) -> None: self.txt = "Hello" def print_txt(self): print(self.txt) return self.txt
初始test_main_0.py
import unittest class TestSomeMain(unittest.TestCase): def test_main_0(self): from src.main.lambda_function.some.main_0 import lambda_handler res = lambda_handler() assert res == "Hello"
已尝试无效操作
在相关目录添加空的__init__.py文件后问题依旧,更新后的目录结构:
some_project └───src ├───main │ └───lambda_function │ └───some │ main_0.py │ s3.py │ __init__.py │ └───test └───unittest └───lambda_function └───some test_main_0.py test_s3.py __init__.py
执行的Pytest命令(在some_project目录下):
python -m pytest ./src/test
注:使用main_0.py而非main.py是为了避免与main目录混淆。
临时解决方案是在test_main_0.py中添加sys.path,但会破坏编辑器的代码提示和语法检查,希望找到更优方案:
import unittest import os import sys sys.path.append(os.path.abspath("./src/main/lambda_function/some/")) class TestSomeMain(unittest.TestCase): def test_main_0(self): from src.main.lambda_function.some.main_0 import lambda_handler # 可行 from main_0 import lambda_handler # 也可行,但破坏编辑器提示 res = lambda_handler() assert res == "Hello"
更优解决方案
方案1:调整导入语句为规范的绝对/相对导入
绝对导入(推荐)
修改main_0.py的导入语句,使用完整模块路径:
from src.main.lambda_function.some.s3 import PrintS3 def lambda_handler(): obj = PrintS3() res = obj.print_txt() return res
相对导入
适用于Python 3环境,利用相对路径导入同目录模块:
from .s3 import PrintS3 def lambda_handler(): obj = PrintS3() res = obj.print_txt() return res
方案2:执行Pytest时添加项目根目录到Python路径
在some_project目录下执行Pytest时,临时将当前目录加入Python模块搜索路径:
- Linux/macOS:
PYTHONPATH=$(pwd) python -m pytest ./src/test
- Windows:
set PYTHONPATH=%cd% && python -m pytest ./src/test
方案3:用pytest.ini统一配置路径
在some_project目录下创建pytest.ini文件,内容如下:
[pytest] pythonpath = .
后续执行Pytest时会自动将项目根目录加入路径,无需每次手动设置环境变量。
方案4:将模块设为可安装包(长期项目首选)
- 在
src/main/lambda_function/some/__init__.py中导出模块内容:
from .main_0 import lambda_handler from .s3 import PrintS3
- 在
some_project目录下创建pyproject.toml文件,示例内容:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "lambda-some" version = "0.1.0" packages = ["src.main.lambda_function.some"]
- 以开发模式安装包:
pip install -e .
这种方式最规范,能完美支持编辑器的代码提示和语法检查,适合长期维护的项目。
内容的提问来源于stack exchange,提问作者SKJ
相关产品推荐
相关产品推荐

