硬编码路径在pytest中报错因工作目录不固定且跨平台分隔符不同;应使用Path(__file__).parent基于测试文件定位资源,配合/拼接、resolve()转绝对路径,并在fixture中封装复用,打包时需通过sys._MEIPASS适配。

硬编码路径在pytest中为什么一跑就报错
因为测试运行时的当前工作目录(os.getcwd())不固定:可能在项目根目录、tests/子目录,甚至CI环境里是临时路径。用"./data/test.csv"或"../config.yaml"这类字符串,一旦执行位置变了,FileNotFoundError立马出现。
更麻烦的是,Windows用反斜杠\,Linux/macOS用正斜杠/,拼接字符串时容易出错。不是路径不存在,是路径根本没按预期构造出来。
用pathlib.Path定位测试资源文件的正确姿势
核心原则:所有路径都基于测试文件自身位置推导,不依赖当前工作目录。pytest推荐做法是用Path(__file__).parent拿到测试模块所在目录,再用/操作符拼接:
from pathlib import Path <h1>假设 test_loader.py 在 tests/unit/ 目录下</h1><p>TEST_DIR = Path(<strong>file</strong>).parent DATA_DIR = TEST_DIR / "data" # 自动处理分隔符 CONFIG_PATH = TEST_DIR / ".." / "config" / "test.yaml"</p><h1>转成绝对路径再读取(防止相对路径失效)</h1><p>config = yaml.safe_load(CONFIG_PATH.resolve().read_text())
-
Path(__file__).parent永远指向当前测试文件所在的目录,稳定可靠 - 用
/操作符拼接,比os.path.join()更直观,且自动适配系统分隔符 - 调用
.resolve()能展开..、消除符号链接、转为绝对路径——这是避免“路径存在但打不开”的关键一步
pathlib在fixture中复用路径逻辑的写法
把路径构造逻辑封装进pytest fixture,避免每个测试函数重复写Path(__file__).parent:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
立即学习“Python免费学习笔记(深入)”;
import pytest from pathlib import Path <p>@pytest.fixture def test_data_dir(): return Path(<strong>file</strong>).parent / "data"</p><p>def test_load_csv(test_data_dir): csv_path = test_data_dir / "sample.csv" assert csv_path.resolve().exists() # 先确认路径真实存在 df = pd.read_csv(csv_path) assert len(df) > 0
- fixture返回
Path对象而非字符串,下游可直接用/继续拼接 - 务必在打开前调用
.resolve().exists()做存在性校验——很多迁移失败其实是因为资源文件没同步到新环境 - 不要在fixture里直接
.read_text()或open(),否则无法支持参数化测试中不同文件的切换
跨平台打包后路径失效的补救方案
PyInstaller或Nuitka打包后,__file__指向临时解压路径,Path(__file__).parent可能找不到原始资源。这时要改用sys._MEIPASS:
import sys
from pathlib import Path
<p>def get_resource_path(relative_path):
if getattr(sys, 'frozen', False):</p><h1>打包后走这里</h1><pre class="brush:php;toolbar:false;"> base_path = Path(sys._MEIPASS)
else:
# 开发时走这里
base_path = Path(__file__).parent
return base_path / relative_pathconfig_path = get_resource_path("config/test.yaml").resolve()
这个判断必须加,否则打包应用在客户机器上一启动就因路径为空崩溃。很多人只测开发环境,上线才暴露问题。

















