必须用 sys.platform 因为它在启动时确定且稳定,而 platform.system() 可能抛 oserror,os.name 无法区分 linux 和 macos;sys.platform 精确等于 "win32"、"linux" 或 "darwin",安全可靠。

为什么必须用 sys.platform 而不是 platform.system() 或 os.name
因为 pytest.mark.skipif 的条件在测试收集阶段(import 时)就求值,而 platform.system() 可能在某些容器或精简环境里抛 OSError 或返回空字符串,导致整个测试收集失败;os.name 返回 "nt" 或 "posix",无法区分 Linux 和 macOS(两者都是 "posix");只有 sys.platform 是启动时确定的稳定常量:"win32"、"linux"、"darwin",且不会在收集阶段出错。
sys.platform == "win32" 是最常用也最安全的 Windows 判断方式
别写成 "win" in sys.platform——旧版 Python 在 Cygwin 下可能返回 "cygwin",导致误跳;也别用大小写不敏感的比较。Windows 环境下永远是精确等于 "win32"。
-
sys.platform == "win32"→ 跳过 Windows -
sys.platform == "linux"→ 跳过 Linux -
sys.platform == "darwin"→ 跳过 macOS - 组合多个平台:
sys.platform in ("win32", "cygwin")(但一般只加"win32"就够了)
类级别跳过必须直接装饰 class 语句本身
把 @pytest.mark.skipif(...) 写在 class 定义上方,而不是类内部、也不是 __init__ 或 setup_method 里。否则它只作用于紧挨着的那个方法,不是整个类。
- ✅ 正确:
@pytest.mark.skipif(sys.platform == "win32", reason="Unix-only class") class TestUnixUtils:
- ❌ 错误:
class TestUnixUtils: @pytest.mark.skipif(...) # 这只影响下一个 def,不是整个类 def test_something(self): - 类被跳过后,
setup_class和teardown_class都不会执行
模块级跳过要用 pytest.skip(..., allow_module_level=True)
如果整个文件都不该在某平台上运行(比如用了 Windows-only 的 DLL),就不能靠装饰器——得在模块顶层调用 pytest.skip() 并传 allow_module_level=True。
- 必须放在 import 之后、任何测试定义之前
- 示例:
import sys import pytest <p>if sys.platform != "linux": pytest.skip("仅限 Linux 模块", allow_module_level=True)</p> - 这个跳过发生在模块导入时,比任何函数或类装饰器都早
跳过逻辑看似简单,但真正容易出问题的地方是:条件表达式里偷偷依赖了尚未 import 的模块、或者用了运行时才有的变量——这些都会让 skipif 静默失效,测试照常跑,却没人发现它本该被跳过。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











