好的,各位观众老爷们,各位屏幕前的代码英雄们,欢迎来到今天的“Python多环境测试与自动化集成:tox 和 nox 讲座”。今天咱们不讲虚的,直接上干货,保证各位听完之后,腰不酸了,腿不疼了,一口气能部署十个版本的Python项目!
开场白:为啥我们需要多环境测试?
话说啊,咱们写代码,就跟养孩子似的。你精心呵护的代码,在你的电脑上跑得飞起,结果到了客户的机器上,直接给你跪了。为啥?环境不一样呗!
就好比你给孩子买了一堆玩具,结果到了姥姥家,姥姥说:“这玩具太危险了,我给你换成拨浪鼓!” 你的孩子肯定不乐意啊!
所以,为了避免这种悲剧发生,我们需要多环境测试,确保我们的代码在各种环境下都能稳如老狗。
主角登场:tox 和 nox,测试界的双子星
tox 和 nox,这两位都是Python测试界的扛把子,都是用来管理和运行多环境测试的。它们就像一对双胞胎,长得像,功能也差不多,但是性格略有不同。
-
tox:老牌劲旅,配置即王道tox是个老江湖了,它的核心思想是“配置即代码”。你需要写一个tox.ini文件,把你的测试环境和测试命令都配置好,然后tox就会自动帮你创建虚拟环境,安装依赖,运行测试。 -
nox:后起之秀,Python代码说了算nox比较年轻,它用 Python 代码来配置测试环境。你可以写一个noxfile.py文件,用 Python 代码来定义你的测试流程。这种方式更加灵活,也更符合 Python 程序员的习惯。
第一幕:tox 的魅力
咱们先来看看 tox 怎么玩。
-
安装
toxpip install tox这没啥好说的,安装就完事了。
-
编写
tox.ini文件这个文件是
tox的灵魂,所有的配置都在这里面。咱们来一个简单的例子:[tox] envlist = py37, py38, py39 [testenv] deps = pytest requests commands = pytest这个
tox.ini文件定义了三个测试环境:py37、py38和py39。每个环境都会安装pytest和requests这两个依赖,然后运行pytest命令。咱们来解释一下这些配置:
envlist:指定要运行的测试环境列表。deps:指定每个环境需要安装的依赖。commands:指定每个环境要运行的命令。
你还可以添加更多配置,比如指定 Python 版本,设置环境变量等等。
配置项 描述 envlist指定要运行的测试环境列表。 可以使用逗号分隔多个环境,也可以使用通配符,比如 py{37,38,39}。deps指定每个环境需要安装的依赖。可以使用 ==、>=、<=等运算符来指定版本。commands指定每个环境要运行的命令。 可以使用多行命令,每行一个命令。 setenv设置环境变量。 可以设置全局环境变量,也可以设置特定环境的环境变量。 passenv允许传递宿主机的环境变量到测试环境。 例如, passenv = HOME, CI*表示传递HOME环境变量和所有以CI开头的环境变量。skip_install如果设置为 True,则跳过依赖的安装。 这在你使用 Poetry 或 Pipenv 管理依赖时很有用。changedir指定测试命令运行的目录。 默认情况下,测试命令在项目根目录运行。 description为测试环境添加描述。 这可以帮助你更好地理解每个测试环境的目的。 -
运行
toxtox运行这个命令,
tox就会自动创建虚拟环境,安装依赖,运行测试。如果只想运行某个特定的环境,可以使用
-e参数:tox -e py38 -
tox.ini的高级用法tox.ini文件可以写得很复杂,它可以包含多个 section,每个 section 可以定义不同的配置。比如,你可以定义一个[testenv:lint]section,用来运行代码检查工具。[tox] envlist = py37, py38, py39, lint [testenv] deps = pytest requests commands = pytest [testenv:lint] deps = flake8 commands = flake8 .这个
tox.ini文件定义了一个lint环境,用来运行flake8代码检查工具。
第二幕:nox 的逆袭
接下来,咱们来看看 nox 怎么玩。
-
安装
noxpip install nox还是那句话,安装就完事了。
-
编写
noxfile.py文件这个文件是
nox的核心,所有的测试流程都用 Python 代码来定义。咱们来一个简单的例子:import nox @nox.session(python=["3.7", "3.8", "3.9"]) def tests(session): session.install("pytest", "requests") session.run("pytest")这个
noxfile.py文件定义了一个testssession,它会在 Python 3.7、3.8 和 3.9 环境下运行。每个环境都会安装pytest和requests这两个依赖,然后运行pytest命令。咱们来解释一下这些代码:
@nox.session:这是一个装饰器,用来定义一个 session。python=["3.7", "3.8", "3.9"]:指定 session 要运行的 Python 版本列表。session.install("pytest", "requests"):安装依赖。session.run("pytest"):运行命令。
nox的灵活性在于,你可以用 Python 代码来做任何事情,比如:- 根据不同的 Python 版本安装不同的依赖。
- 根据不同的操作系统运行不同的命令。
- 自定义测试流程。
-
运行
noxnox运行这个命令,
nox就会自动创建虚拟环境,安装依赖,运行测试。如果只想运行某个特定的 session,可以使用
-s参数:nox -s tests -
noxfile.py的高级用法noxfile.py文件可以写得很复杂,它可以包含多个 session,每个 session 可以定义不同的测试流程。比如,你可以定义一个lintsession,用来运行代码检查工具。import nox @nox.session(python=["3.7", "3.8", "3.9"]) def tests(session): session.install("pytest", "requests") session.run("pytest") @nox.session def lint(session): session.install("flake8") session.run("flake8", ".")这个
noxfile.py文件定义了一个lintsession,用来运行flake8代码检查工具。
第三幕:tox 和 nox 的爱恨情仇
tox 和 nox 都是好工具,但是它们也有各自的优缺点。
| 特性 | tox |
nox |
|---|---|---|
| 配置方式 | tox.ini 文件,配置即代码 |
noxfile.py 文件,Python 代码 |
| 灵活性 | 相对较低 | 较高,可以用 Python 代码做任何事情 |
| 学习曲线 | 简单,容易上手 | 稍高,需要熟悉 Python 代码 |
| 适用场景 | 简单的多环境测试,配置变化不大 | 复杂的测试流程,需要根据不同的环境做不同的处理 |
| 可扩展性 | 可以通过插件扩展,但相对有限 | 可以用 Python 代码扩展,非常灵活 |
| 与 CI 集成 | 广泛支持,很多 CI 工具都原生支持 tox |
需要自己编写脚本来调用 nox,但也很容易 |
| 依赖管理 | 依赖于 pip,可以指定依赖版本 |
依赖于 pip,也可以结合 Poetry 或 Pipenv 使用,更加灵活 |
| 社区支持 | 活跃,文档完善 | 活跃,文档完善 |
总的来说,如果你只需要简单的多环境测试,tox 是一个不错的选择。如果你需要更灵活的测试流程,或者你需要根据不同的环境做不同的处理,nox 可能会更适合你。
第四幕:实战演练
光说不练假把式,咱们来一个实战演练。
假设咱们有一个简单的 Python 项目,它的目录结构如下:
myproject/
├── mymodule/
│ ├── __init__.py
│ └── myfunction.py
├── tests/
│ ├── __init__.py
│ └── test_myfunction.py
├── pyproject.toml # 使用 Poetry 管理依赖
└── README.md
mymodule/myfunction.py 包含一个简单的函数:
def add(a, b):
return a + b
tests/test_myfunction.py 包含一个简单的测试:
from mymodule.myfunction import add
def test_add():
assert add(1, 2) == 3
咱们使用 Poetry 来管理依赖,pyproject.toml 文件的内容如下:
[tool.poetry]
name = "myproject"
version = "0.1.0"
description = ""
authors = ["Your Name <[email protected]>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.7"
[tool.poetry.dev-dependencies]
pytest = "^6.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
接下来,咱们分别用 tox 和 nox 来配置多环境测试。
-
使用
tox创建一个
tox.ini文件:[tox] envlist = py37, py38, py39 [testenv] deps = pytest # 如果你使用 Poetry,可以注释掉上面的 deps,使用下面这行 # {[testenv]deps} commands = pytest如果你使用 Poetry 管理依赖,需要注释掉
deps配置,并添加{[testenv]deps}。这样tox就会使用 Poetry 安装依赖。运行
tox命令,就可以看到测试结果了。 -
使用
nox创建一个
noxfile.py文件:import nox @nox.session(python=["3.7", "3.8", "3.9"]) def tests(session): # 如果你使用 Poetry,可以使用下面这行来安装依赖 session.run("poetry", "install", external=True) session.install("pytest") # 如果不使用 poetry,就用这个 session.run("pytest")如果你使用 Poetry 管理依赖,可以使用
session.run("poetry", "install", external=True)来安装依赖。external=True表示运行外部命令。运行
nox命令,就可以看到测试结果了。
第五幕:与 CI 集成
多环境测试的最终目的是为了自动化集成。咱们可以将 tox 或 nox 集成到 CI 工具中,比如 GitHub Actions、GitLab CI 等。
以 GitHub Actions 为例,创建一个 .github/workflows/test.yml 文件:
name: Tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8, 3.9]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install poetry
poetry install
- name: Test with pytest
run: |
pytest
这个 GitHub Actions workflow 会在 Python 3.7、3.8 和 3.9 环境下运行测试。
如果你使用 tox,可以将测试命令改为 tox:
- name: Test with tox
run: |
tox
如果你使用 nox,可以将测试命令改为 nox:
- name: Test with nox
run: |
nox
剧终:总结与展望
今天咱们聊了 tox 和 nox 这两个多环境测试工具,它们可以帮助我们确保代码在各种环境下都能正常运行。
总的来说,tox 简单易用,适合简单的多环境测试。nox 灵活强大,适合复杂的测试流程。你可以根据自己的需求选择合适的工具。
希望今天的讲座对大家有所帮助。记住,代码质量是项目的生命线,多环境测试是保证代码质量的重要手段。
各位观众老爷们,咱们下期再见!