如何使用pytest仅在本地运行指定测试而不触发CI执行?
pytest 本地专属测试用例实现方案
你原来在函数内部判断环境变量的写法虽然能跑,但有个明显的问题:如果条件不满足,测试会直接被判定为通过,你没法从测试结果里直观看到这个用例有没有实际执行。pytest 原生提供了更规范的实现方式,推荐使用 pytest.mark.skipif 相关能力来实现。
方案1:单测试用例快速适配
绝大多数 CI 环境(Github Actions、Gitlab CI、Jenkins 等)都会默认设置全局的 CI 环境变量,你可以直接基于这个变量判断,不需要自己额外定义专属环境变量:
import os import pytest # 检测到CI环境变量时自动跳过该测试 @pytest.mark.skipif("CI" in os.environ, reason="仅允许在本地运行,CI环境跳过") def test_something_local_only(): # 直接写测试逻辑即可,不需要额外加分支判断 assert 1 + 1 == 2
如果你希望用自定义的环境变量控制执行逻辑,只需要修改 skipif 的判断条件即可:
# 只有存在MY_LOCAL_RUN_KEY环境变量时才执行该测试 @pytest.mark.skipif("MY_LOCAL_RUN_KEY" not in os.environ, reason="未检测到本地运行标记,跳过测试") def test_something_local_only(): # 测试逻辑
方案2:批量管理本地测试用例
如果你有大量需要在本地运行的测试用例,每次都写一遍 skipif 逻辑太冗余,可以自定义 pytest 标记统一管理:
步骤1:注册自定义标记
在项目根目录的 pytest 配置文件(pytest.ini 或 pyproject.toml)中注册标记,避免 pytest 报未知标记警告,以 pytest.ini 为例:
[pytest] markers = local_only: 标记仅允许在本地运行的测试用例
步骤2:添加全局跳过逻辑
在根目录的 conftest.py 中添加钩子函数,统一处理标记的跳过逻辑:
import os import pytest def pytest_runtest_setup(item): # 测试用例带local_only标记且当前在CI环境时,自动跳过 if "local_only" in item.keywords and "CI" in os.environ: pytest.skip("local_only标记的用例不在CI环境执行")
步骤3:给测试用例加标记
后续需要仅在本地运行的用例,直接加标记即可:
@pytest.mark.local_only def test_case1(): pass @pytest.mark.local_only def test_case2(): pass
方案3:支持命令行灵活控制
如果你需要偶尔在 CI 环境手动执行这些本地用例,可以额外添加自定义命令行参数控制:
- 先在
conftest.py中添加命令行参数配置和逻辑:
import pytest def pytest_addoption(parser): parser.addoption( "--run-local", action="store_true", default=False, help="运行所有标记为local_only的本地专属用例" ) def pytest_collection_modifyitems(config, items): # 带--run-local参数时不跳过本地用例 if config.getoption("--run-local"): return # 否则跳过所有local_only标记的用例 skip_mark = pytest.mark.skip(reason="需添加--run-local参数才会执行该用例") for item in items: if "local_only" in item.keywords: item.add_marker(skip_mark)
- 本地运行测试时,添加参数即可执行所有本地专属用例:
pytest --run-local
CI 环境默认不带这个参数,会自动跳过所有 local_only 标记的用例。
内容的提问来源于stack exchange,提问作者baxx
相关产品推荐
相关产品推荐

