好的,各位观众老爷们,各位屏幕前的代码英雄们,欢迎来到今天的“Python多环境测试与自动化集成:tox
和 nox
讲座”。今天咱们不讲虚的,直接上干货,保证各位听完之后,腰不酸了,腿不疼了,一口气能部署十个版本的Python项目!
开场白:为啥我们需要多环境测试?
话说啊,咱们写代码,就跟养孩子似的。你精心呵护的代码,在你的电脑上跑得飞起,结果到了客户的机器上,直接给你跪了。为啥?环境不一样呗!
就好比你给孩子买了一堆玩具,结果到了姥姥家,姥姥说:“这玩具太危险了,我给你换成拨浪鼓!” 你的孩子肯定不乐意啊!
所以,为了避免这种悲剧发生,我们需要多环境测试,确保我们的代码在各种环境下都能稳如老狗。
主角登场:tox
和 nox
,测试界的双子星
tox
和 nox
,这两位都是Python测试界的扛把子,都是用来管理和运行多环境测试的。它们就像一对双胞胎,长得像,功能也差不多,但是性格略有不同。
-
tox
:老牌劲旅,配置即王道tox
是个老江湖了,它的核心思想是“配置即代码”。你需要写一个tox.ini
文件,把你的测试环境和测试命令都配置好,然后tox
就会自动帮你创建虚拟环境,安装依赖,运行测试。 -
nox
:后起之秀,Python代码说了算nox
比较年轻,它用 Python 代码来配置测试环境。你可以写一个noxfile.py
文件,用 Python 代码来定义你的测试流程。这种方式更加灵活,也更符合 Python 程序员的习惯。
第一幕:tox
的魅力
咱们先来看看 tox
怎么玩。
-
安装
tox
pip 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
为测试环境添加描述。 这可以帮助你更好地理解每个测试环境的目的。 -
运行
tox
tox
运行这个命令,
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
怎么玩。
-
安装
nox
pip 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
文件定义了一个tests
session,它会在 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 版本安装不同的依赖。
- 根据不同的操作系统运行不同的命令。
- 自定义测试流程。
-
运行
nox
nox
运行这个命令,
nox
就会自动创建虚拟环境,安装依赖,运行测试。如果只想运行某个特定的 session,可以使用
-s
参数:nox -s tests
-
noxfile.py
的高级用法noxfile.py
文件可以写得很复杂,它可以包含多个 session,每个 session 可以定义不同的测试流程。比如,你可以定义一个lint
session,用来运行代码检查工具。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
文件定义了一个lint
session,用来运行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
灵活强大,适合复杂的测试流程。你可以根据自己的需求选择合适的工具。
希望今天的讲座对大家有所帮助。记住,代码质量是项目的生命线,多环境测试是保证代码质量的重要手段。
各位观众老爷们,咱们下期再见!