如何配置setuptools让单元测试依赖本地未安装的并行开发包?
解决并行开发时本地依赖的测试问题(无需安装依赖包)
假设你的项目目录结构是这样的:
workspace/ ├── package_a/ # 你的A包 │ ├── package_a/ │ │ └── __init__.py │ └── setup.py └── package_b/ # 依赖A的B包 ├── package_b/ │ └── __init__.py ├── tests/ │ └── test_b.py └── setup.py
下面是几种无需安装A包就能让B的测试正常导入A的实用方案:
方法1:在测试入口动态添加A的路径(简单直接)
这种方法不用大改setup.py,只需要在测试的全局配置文件里给Python路径加个“快捷方式”就行。
- 在package_b的
tests目录下创建conftest.py(pytest全局配置文件),内容如下:
import sys from pathlib import Path # 计算本地A包的根目录路径(相对于B的测试目录) package_a_root = Path(__file__).parent.parent.parent / "package_a" # 把A的路径插入到Python模块搜索路径的最前面 sys.path.insert(0, str(package_a_root))
这样每次运行B的测试时,Python都会优先从本地并行的A目录导入代码,不会去找已安装的版本。
- 同时在package_b的setup.py里配置好测试依赖:
from setuptools import setup, find_packages setup( name="package_b", version="0.1.0", packages=find_packages(), # 声明测试需要的依赖 tests_require=["pytest>=6.0"], # 可选:直接把pytest设为测试命令 cmdclass={"test": pytest.cmdline.main}, )
方法2:利用setuptools的可编辑安装(轻量持久)
虽然你提到不想“持续安装”,但**可编辑安装(editable install)**并不是真的把A包复制到Python环境里,只是创建一个符号链接,本地修改A的代码后,B的测试会立即生效,非常适合长期并行开发。
- 先进入package_a的目录,运行:
pip install -e .
这会把A包以“可编辑模式”注册到当前Python环境,之后B的代码(包括测试)就能直接导入A,无需额外配置。
- 怕影响全局环境?用虚拟环境隔离就好:
# 在package_b目录创建并激活虚拟环境 python -m venv venv source venv/bin/activate # Windows系统用 venv\Scripts\activate # 安装A的可编辑版本 pip install -e ../package_a # 运行B的测试 pytest tests/
这种方式完全隔离在虚拟环境里,不会污染全局Python环境,而且A的任何修改都会实时同步到B的测试中。
方法3:在setup.py中指定本地依赖路径(固化开发配置)
如果你希望把B的开发依赖配置固化到setup.py里,可以直接在install_requires中指定A的本地路径:
from setuptools import setup, find_packages from pathlib import Path setup( name="package_b", version="0.1.0", packages=find_packages(), install_requires=[ # 用file URL指定本地A包的绝对路径 "package_a @ file://localhost/{}".format( Path(__file__).parent.parent / "package_a" ) ], tests_require=["pytest>=6.0"], )
然后安装B的可编辑版本:
pip install -e .
这样B会自动关联本地并行的A包,运行测试时直接使用A的本地目录,无需单独安装A。注意这种方法需要pip版本 >= 19.0。
总结
- 临时测试选方法1,零环境改动,快速生效;
- 长期并行开发选方法2,兼顾便捷性和实时同步;
- 要固化开发环境配置选方法3,把依赖关系写进setup.py里。
内容的提问来源于stack exchange,提问作者jpp1




