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

使用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:将模块设为可安装包(长期项目首选)

  1. 在src/main/lambda_function/some/__init__.py中导出模块内容:
from .main_0 import lambda_handler
from .s3 import PrintS3
  1. 在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"]
  1. 以开发模式安装包:
pip install -e .

这种方式最规范,能完美支持编辑器的代码提示和语法检查,适合长期维护的项目。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:25:17