Python单元测试同包模块导入失败问题求助
同包模块导入导致单元测试失败的问题解决
问题背景
单元测试时,被测模块导入同包内其他模块会直接失败。项目使用VS Code + pytest在Azure Pipelines运行测试,构建的wheel包在Databricks ETL管道中运行完全正常,但测试环节无法处理跨模块导入,目前只能临时跳过相关测试,急需长期解决方案。
项目目录结构
Project_Dir: src: my_package: __init__.py my_module.py my_other_module.py test: my_package: __init__.py my_module_test.py
(注:原目录标注的package_dir应为my_package,与代码中的包名匹配)
相关代码
测试代码(my_module_test.py)
import unittest from my_package.my_module import MyClass class TestMyModule(unittest.TestCase): def setUp(self): pass def test_multiple(self): test_obj = MyClass() test_obj.do_something()
(注:原代码中test_multiple未缩进为类方法,已修正)
模块代码(my_module.py)
import my_other_module class MyClass: def __init__(self): pass def do_something(self): obj = my_other_module.MyOtherClass() obj.my_other_method() print("Called other method!")
错误信息
2023-12-20 11:33:15.311 [info] > "C:\Program Files\Python312\python.exe" ~\.vscode\extensions\ms-python.python-2023.22.1\pythonFiles\unittestadapter\discovery.py --udiscovery -v -s ./test/ -p *_test.py 2023-12-20 11:33:15.311 [info] cwd: c:\GitRepos\AzureDevops-Intellimax\Python-SampleProjects\Import Issue reproduce project 2023-12-20 11:33:15.510 [info] Test server connected to a client. 2023-12-20 11:33:15.514 [error] Unittest test discovery error for workspace: c:\GitRepos\AzureDevops-Intellimax\Python-SampleProjects\Import Issue reproduce project Failed to import test module: my_package.my_module_test Traceback (most recent call last): File "C:\Program Files\Python312\Lib\unittest\loader.py", line 382, in _find_test_path module = self._get_module_from_name(name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\unittest\loader.py", line 325, in _get_module_from_name __import__(name) File "c:\GitRepos\AzureDevops-Intellimax\Python-SampleProjects\Import Issue reproduce project\test\my_package\my_module_test.py", line 2, in <module> from src.my_package.my_module import MyClass File "c:\GitRepos\AzureDevops-Intellimax\Python-SampleProjects\Import Issue reproduce project\src\my_package\my_module.py", line 1, in <module> import my_other_module ModuleNotFoundError: No module named 'my_other_module'
解决方案
1. 修正模块内的导入语句
模块内的同包导入需使用标准的相对或绝对导入方式,避免直接导入模块名:
- 相对导入(推荐,保持包内独立性):
from . import my_other_module # 或直接导入目标类,更简洁 from .my_other_module import MyOtherClass - 绝对导入(适用于明确包名的场景):
from my_package import my_other_module
2. 调整测试代码的导入路径
测试代码中移除src前缀,直接导入包内模块:
# 错误写法:from src.my_package.my_module import MyClass from my_package.my_module import MyClass
3. 将src目录加入Python搜索路径
测试运行时,Python需要能找到src下的包,可通过以下方式配置:
- 本地VS Code:
在项目根目录创建.env文件,添加:
然后在VS Code的PYTHONPATH=./srcsettings.json中指定环境文件:"python.envFile": "${workspaceFolder}/.env" - Azure Pipelines:
在流水线yml中添加设置PYTHONPATH的步骤:- script: | export PYTHONPATH=$(Build.SourcesDirectory)/src displayName: 'Set Python Path for Testing' - 命令行运行pytest:
Windows:
Linux/macOS:set PYTHONPATH=%cd%\src && pytest test/ -vexport PYTHONPATH=$(pwd)/src && pytest test/ -v
4. 可选:安装包的开发模式
如果项目用setup.py或pyproject.toml管理,可安装开发模式让Python自动识别包路径:
pip install -e .
(需确保配置文件中正确指定packages参数指向src/my_package)
原因说明
wheel包安装后,my_package会被放入Python的site-packages全局导入目录,因此模块内的导入能正常工作;而测试时直接运行代码,Python默认不会将项目根目录下的src加入搜索路径,加上模块内使用了非标准的同包导入方式,最终导致找不到模块。
内容的提问来源于stack exchange,提问作者Alan Blyth
相关产品推荐
相关产品推荐

