如何将tox测试环境的依赖包版本冻结至requirements.txt文件?
如何用tox将依赖版本冻结到requirements.txt?
我通常用requirements.in管理抽象依赖:
# requirements.in pytest
在tox.ini中定义的测试环境配置如下:
[testenv] deps = -rrequirements.in commands = pytest
我想把测试环境中已安装的依赖包版本冻结到指定文件,尝试在tox.ini里添加如下命令:
commands_post = python -m pip freeze --all > requirements.d/pytest.txt
但执行时发现重定向符号>被转义了,命令实际变成把'>'和requirements.d/pytest.txt当作参数传给pip freeze,导致依赖信息直接输出到标准输出,没有写入目标文件:
pytest-py312: commands_post[0]> python -m pip freeze --all '>' requirements.d/pytest.txt
解决方法
方法1:显式调用shell执行命令
tox默认不会将命令交给系统shell解析,因此重定向这类shell语法无法生效。可以直接调用shell来执行完整命令:
# Linux/macOS环境用bash commands_post = bash -c "python -m pip freeze --all > requirements.d/pytest.txt" # Windows环境用cmd commands_post = cmd /c "python -m pip freeze --all > requirements.d/pytest.txt"
方法2:开启tox的shell模式
在[testenv]配置块中开启shell = True,这样所有commands和commands_post都会通过系统shell执行,重定向符号就能正常解析:
[testenv] deps = -rrequirements.in commands = pytest shell = True commands_post = python -m pip freeze --all > requirements.d/pytest.txt
注意:开启该模式后所有命令都会走shell,需注意跨平台兼容性。
方法3:用pip-tools生成更干净的依赖冻结文件
如果只需要冻结requirements.in中声明的依赖及其间接依赖(而非环境中所有包),可以使用pip-tools的pip-compile命令:
- 先在tox的依赖中添加
pip-tools:
[testenv] deps = -rrequirements.in pip-tools
- 修改
commands_post执行编译命令:
commands_post = pip-compile requirements.in --output-file requirements.d/pytest.txt
这样生成的文件只会包含pytest及其必要依赖的精确版本,比pip freeze --all的结果更简洁可控。
内容的提问来源于stack exchange,提问作者Bengt
相关产品推荐
相关产品推荐

