tmp_path比tempfile.mkdtemp()更安全,因其为pytest内置函数级fixture,每次测试创建唯一临时目录,测试结束自动调用shutil.rmtree清理;而mkdtemp()需手动清理,易残留文件、引发并发冲突或权限错误。

tmp_path 为什么比 tempfile.mkdtemp() 更安全?
因为 tmp_path 是 pytest 内置 fixture,测试结束自动清理,不会残留空目录或文件;而手动用 tempfile.mkdtemp() 忘记 shutil.rmtree() 就容易污染开发环境,CI 里还可能因权限或并发导致冲突。
它返回的是 pathlib.Path 对象,不是字符串路径,直接支持 .joinpath()、.write_text() 等操作,不用再拼接 os.path.join()。
怎么在测试函数里直接用 tmp_path 创建子目录和文件?
pytest 自动注入,直接当参数写进函数签名就行,不用 import 或 setup/teardown:
def test_read_config(tmp_path):
config_dir = tmp_path / "etc" / "myapp"
config_dir.mkdir(parents=True)
(config_dir / "settings.ini").write_text("[db]\nhost=localhost")
<pre class="brush:php;toolbar:false;"># 后续调用你的真实函数读取这个路径
result = load_config(config_dir)
assert result["db"]["host"] == "localhost"-
tmp_path每次测试都是全新、隔离的路径,不同测试间不共享 - 支持
/运算符拼接子路径,比tmp_path.joinpath("a", "b")更简洁 - 如果要创建带内容的文件,优先用
.write_text()或.write_bytes(),别用内置open()再手动 close
tmp_path 和 tmp_path_factory 有什么区别?
tmp_path 是函数级 fixture,每个测试函数一份;tmp_path_factory 是会话级 fixture,适合需要跨多个测试共享临时数据(比如预生成一个大测试文件),但必须显式调用 mktemp() 创建子目录:
@pytest.fixture(scope="session")
def large_test_data(tmp_path_factory):
data_dir = tmp_path_factory.mktemp("data")
(data_dir / "big.csv").write_bytes(b"a,b,c\n1,2,3\n" * 10000)
return data_dir
<p>def test_process_large_file(large_test_data):
process_csv(large_test_data / "big.csv")
</p>
- 误把
tmp_path_factory当tmp_path直接用会报AttributeError: 'TempPathFactory' object has no attribute 'joinpath' - 共享目录意味着多个测试可能并发读写同一路径,得自己加锁或确保只读
- 除非真有性能或生成开销问题,否则优先用
tmp_path,更简单、更隔离
常见错误:PermissionError 或 FileNotFoundError 怎么排查?
典型现象是 Windows 上报 PermissionError: [WinError 5] Access is denied,或 Linux/macOS 下 FileNotFoundError 却确认路径存在——本质是路径对象没“落地”成真实文件系统实体:
- 只写了
tmp_path / "sub"没调.mkdir(),后续.write_text()会失败(父目录不存在) - 用
open(str(tmp_path / "file.txt"), "w")时,str()转换没问题,但漏了创建父目录逻辑 - 在 subprocess 里调外部命令读写该路径时,确保传的是
str(tmp_path)或tmp_path.as_posix(),别传Path对象本身(某些老命令不认) - pytest 7.0+ 默认禁用
tmpdirfixture,如果项目里混用了旧写法(比如def test_x(tmpdir):),会静默跳过并报错说 fixture 未定义
临时目录的生命周期完全由 pytest 控制,别在测试函数 return 后还试图访问它里面的文件——那块磁盘空间可能已经被清掉了。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











