在pytest中,想要让每个测试用例都自动拥有一个独立的临时目录,最方便的做法是利用框架自带的临时目录fixture,或者基于它们封装自己的fixture。这样可以保证用例之间互不影响,运行完也会自动清理。

为什么需要临时目录fixture
测试过程中经常要写文件、建缓存或者下载资源。如果所有用例共用一个目录,就可能因为文件重名或状态残留导致偶发失败。用fixture自动给每个用例创建临时目录,就能做到环境隔离。
使用内置的tmp_path
pytest已经提供了名为tmp_path的fixture,它是pathlib.Path类型,每个测试用例都会拿到一个全新路径。下面这个例子展示了直接用它:
import os
def test_write_file(tmp_path):
# tmp_path是pytest提供的临时目录,每个用例不同
target = tmp_path / "demo.txt"
target.write_text("hello pytest")
assert target.read_text() == "hello pytest"
assert os.path.exists(target)
自定义fixture自动创建目录
如果你希望目录结构更明确,比如每个用例里都有一个叫work的子类目录,可以自己写fixture包一层:
import pytest
@pytest.fixture
def case_dir(tmp_path):
# 在临时目录下再建一个work文件夹
d = tmp_path / "work"
d.mkdir()
return d
def test_in_case_dir(case_dir):
f = case_dir / "a.log"
f.write_text("log content")
assert f.exists()
fixture作用范围说明
默认fixture是函数级(function),也就是每个测试函数都会重新执行,临时目录自然也是新的。如果设成class或module,同一批用例会共用一个临时目录。一般建议保持默认即可。
| scope值 | 含义 |
|---|---|
| function | 每个测试函数独立临时目录 |
| class | 同一个测试类共用 |
| module | 同一个测试文件共用 |
小结
写fixture自动给用例创建临时目录非常简单:直接用tmp_path,或者用@pytest.fixture包一层tmp_path再做定制。牢记默认的function级作用范围就能满足绝大多数隔离需求。