该用@pytest.mark.skip而非删除测试,是在面对API临时下线、平台不支持或需手动干预等「暂时不可运行」场景时,既保留验证意图又明确标注跳过原因;它使测试仍被收集并计为skipped,便于统计覆盖率缺口。

什么时候该用 pytest.mark.skip 而不是直接删测试?
跳过测试不是为了掩盖问题,而是应对「暂时不可运行」的场景:比如依赖的 API 临时下线、某个平台不支持某功能(如 Windows 上跑 macOS 专属逻辑)、或测试需手动干预(如弹窗确认)。删掉测试会丢失验证意图,而 @pytest.mark.skip 明确表达了“我本意是测,但此刻不执行”。
注意:它不会影响测试收集过程——被标记的测试仍会计入 pytest 总数(显示为 skipped),便于统计覆盖率缺口。
@pytest.mark.skip 的两种写法和关键区别
最常用的是装饰器形式,必须紧贴测试函数上方;另一种是参数化跳过(@pytest.mark.skipif),用于条件判断。两者不能混用在同一函数上。
-
@pytest.mark.skip:无条件跳过,适合临时调试时快速屏蔽 -
@pytest.mark.skipif(condition, reason="..."):condition 为True时跳过,推荐用于跨平台或版本兼容场景
示例:
立即学习“Python免费学习笔记(深入)”;
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
@pytest.mark.skip(reason="API v2 not ready")
def test_user_creation():
assert create_user() == "ok"
@pytest.mark.skipif(sys.platform == "win32", reason="Only runs on Unix")
def test_signal_handling():
assert signal.getsignal(signal.SIGUSR1) is not None
为什么加了 @pytest.mark.skip 却没跳过?常见漏点
跳过失效通常不是语法错,而是执行环境或标记位置不对:
- 装饰器写在了
def行下面(必须紧贴函数定义上方) - 用了
pytest.skip()(这是运行时跳过,属于raise行为,和mark.skip完全不同) - 测试被
pytest-xdist并行执行时,某些插件可能干扰标记解析(极少见,可加-v确认是否显示skipped) - pytest 版本太老(
pytest < 3.0不支持部分参数写法,建议 ≥ 6.0)
跳过测试对 CI/CD 和覆盖率的影响
CI 流程中,被 skip 的测试默认不报错,但会记录在 pytest 输出里(如 1 skipped, 12 passed)。如果团队要求“零 skipped”,就得定期清理或转为 xfail。
覆盖率工具(如 coverage.py)默认不统计被跳过测试的代码行——哪怕函数体里有未覆盖分支,只要测试被 skip,那部分就不计入缺失覆盖率。这点容易误判真实覆盖水位。
真正麻烦的是嵌套跳过:比如一个被 skip 的测试里又调用了另一个函数,那个函数里的逻辑就彻底“隐身”了,连日志都看不到。这时候得靠单元测试拆分或临时改用 pytest.skip("reason") 运行时跳过,才能确认路径是否真能走到。

















