
本文详解在 uv 生态下,通过合理配置 pyproject.toml 和目录结构,使 uv tool run pytest 能自动识别 src/ 模块、正确加载测试用例,并无缝访问 requirements.txt 中声明的第三方依赖(如 TensorFlow)。
本文详解在 `uv` 生态下,通过合理配置 `pyproject.toml` 和目录结构,使 `uv tool run pytest` 能自动识别 `src/` 模块、正确加载测试用例,并无缝访问 `requirements.txt` 中声明的第三方依赖(如 tensorflow)。
要在项目根目录下成功执行 uv tool run pytest 并让测试文件(如 tests/test_file1.py)正常导入 src/ 下的模块(例如 from file1 import Class1),需同时解决Python 模块路径解析和工具运行时依赖隔离两大核心问题。uv tool run 默认在隔离环境中执行工具,不会自动继承当前环境的已安装包或 PYTHONPATH,因此必须显式配置。
✅ 正确做法:三步到位
1. 确保 tests/ 是合法 Python 包(关键!)
在 tests/ 目录下创建空的 __init__.py 文件:
touch tests/__init__.py
这使得 tests 成为一个可导入的包,更重要的是——pytest 会据此将 tests/ 的父目录(即项目根目录)自动加入 sys.path。这是 pytest 的默认行为,但前提是 tests/ 是包。没有它,from file1 import Class1 必然失败。
2. 配置 pyproject.toml 显式扩展模块搜索路径
在 pyproject.toml 中添加 pytest 配置,确保 src/ 和项目根目录均被识别:
[tool.pytest.ini_options] # 将项目根目录(".")加入 Python 模块搜索路径 → 支持 "from file1 import ..." # 将 "src" 加入路径 → 支持 "from src.file1 import ..."(更规范) pythonpath = [".", "src"] # 可选:指定测试目录,避免 pytest 扫描错误位置 testpaths = ["tests"] # 可选:启用更严格的导入检查(调试时推荐) import_mode = "importlib"
⚠️ 注意:pythonpath = ["."] 是解决 from file1 import Class1 能直接导入的关键;而 pythonpath = ["src"] 则支持带命名空间的导入。两者可共存。
3. 使用 uv tool run 正确加载依赖环境
uv tool run pytest 不会复用你本地 uv pip install 安装的全局包,它会为 pytest 创建一个临时、干净的工具环境。因此,必须让该环境“知道”你的项目依赖:
-
✅ 推荐方式(零配置):使用
--with参数显式注入依赖uv tool run --with tensorflow==2.18.0 --with pytest pytest
或更通用(从
requirements.txt自动读取):uv tool run --with-requires requirements.txt pytest
-
✅ 进阶方式:定义可复用的
tool(推荐长期维护)
在pyproject.toml中声明pytest工具及其依赖:[tool.uv.tool] pytest = { requires = ["pytest", "tensorflow==2.18.0"], script = "pytest" }然后直接运行:
uv tool run pytest
此时
uv会自动解析并安装requires中所有依赖到专用工具环境,且该环境自动继承pythonpath配置。
? 验证示例
假设 src/file1.py 内容为:
class Class1:
def greet(self):
return "Hello from src!"
tests/test_file1.py 可安全写作:
# ✅ 两种写法均有效(得益于 pythonpath = [".", "src"])
from file1 import Class1 # ← 推荐:扁平化结构,简洁
# from src.file1 import Class1 # ← 备选:显式命名空间
def test_class1_greet():
assert Class1().greet() == "Hello from src!"
⚠️ 常见误区与注意事项
-
uv pip install --editable ./对uv tool run无效:该命令仅影响当前 Python 环境,而tool run总是启动新隔离环境。 - 不要手动修改
PYTHONPATH环境变量:uv工具链不保证其传递给子进程,应始终通过pyproject.toml配置。 -
requirements.txt仅用于uv pip install,不会被uv tool run自动读取——必须显式使用--with-requires或tool.uv.tool配置。 - 若使用
src/结构,建议在pyproject.toml中补充 PEP 517 构建后端配置(非必需,但更规范):[build-system] requires = ["setuptools>=45", "wheel"] build-backend = "setuptools.build_meta"
完成以上配置后,在项目根目录执行:
uv tool run --with-requires requirements.txt pytest
即可看到所有 tests/ 下的用例被正确发现、src/ 模块被顺利导入、TensorFlow 等依赖被准确加载——整个流程完全基于 uv,无需 Poetry、pipx 或虚拟环境手动管理。










