如何在测试中使用临时目录和文件¶
tmp_path fixture¶
你可以使用 tmp_path fixture,它将为每个测试函数提供一个唯一的临时目录。
tmp_path 是一个 pathlib.Path 对象。这是一个示例测试用法
# content of test_tmp_path.py
CONTENT = "content"
def test_create_file(tmp_path):
d = tmp_path / "sub"
d.mkdir()
p = d / "hello.txt"
p.write_text(CONTENT, encoding="utf-8")
assert p.read_text(encoding="utf-8") == CONTENT
assert len(list(tmp_path.iterdir())) == 1
assert 0
运行此代码将导致测试通过,除了最后一行 assert 0,我们用它来查看值
$ pytest test_tmp_path.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-9.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
test_tmp_path.py F [100%]
================================= FAILURES =================================
_____________________________ test_create_file _____________________________
tmp_path = PosixPath('PYTEST_TMPDIR/test_create_file0')
def test_create_file(tmp_path):
d = tmp_path / "sub"
d.mkdir()
p = d / "hello.txt"
p.write_text(CONTENT, encoding="utf-8")
assert p.read_text(encoding="utf-8") == CONTENT
assert len(list(tmp_path.iterdir())) == 1
> assert 0
E assert 0
test_tmp_path.py:11: AssertionError
========================= short test summary info ==========================
FAILED test_tmp_path.py::test_create_file - assert 0
============================ 1 failed in 0.12s =============================
默认情况下,pytest 会保留最近 3 次 pytest 调用的临时目录。通过将基本临时目录配置为每次并发运行唯一,支持相同测试函数的并发调用。有关详细信息,请参阅临时目录位置和保留。
tmp_path_factory fixture¶
tmp_path_factory 是一个会话范围的 fixture,可用于从任何其他 fixture 或测试创建任意临时目录。
例如,假设你的测试套件需要一个磁盘上的大图像,该图像是程序生成的。与其为每个使用该图像的测试将其计算到自己的 tmp_path 中,不如在每个会话中生成一次以节省时间
# contents of conftest.py
import pytest
@pytest.fixture(scope="session")
def image_file(tmp_path_factory):
img = compute_expensive_image()
fn = tmp_path_factory.mktemp("data") / "img.png"
img.save(fn)
return fn
# contents of test_image.py
def test_histogram(image_file):
img = load_image(image_file)
# compute and test histogram
有关详细信息,请参阅tmp_path_factory API。
tmpdir 和 tmpdir_factory fixtures¶
tmpdir 和 tmpdir_factory fixtures 类似于 tmp_path 和 tmp_path_factory,但使用/返回旧的 py.path.local 对象,而不是标准的 pathlib.Path 对象。
注意
如今,更推荐使用 tmp_path 和 tmp_path_factory。
为了帮助现代化旧代码库,可以禁用 legacypath 插件运行 pytest
pytest -p no:legacypath
这将在使用旧路径的测试上触发错误。也可以将其作为配置文件中 addopts 参数的一部分永久设置。
有关详细信息,请参阅 tmpdir tmpdir_factory API。
临时目录位置和保留¶
由 tmp_path 和(现已弃用)tmpdir fixtures 返回的临时目录会在一个基本临时目录下自动创建,其结构取决于 --basetemp 选项
默认情况下(未设置
--basetemp选项时),临时目录将遵循此模板{temproot}/pytest-of-{user}/pytest-{num}/{testname}/其中
{temproot}是由tempfile.gettempdir()确定的系统临时目录。它可以通过PYTEST_DEBUG_TEMPROOT环境变量覆盖。{user}是运行测试的用户名,{num}是一个数字,每次测试套件运行都会递增{testname}是当前测试的名称的净化版本。
自递增的
{num}占位符提供了基本的保留功能,并避免了盲目删除先前测试运行的现有结果。默认情况下,保留最近 3 个临时目录,但此行为可以通过tmp_path_retention_count和tmp_path_retention_policy进行配置。当使用
--basetemp选项时(例如pytest --basetemp=mydir),它将直接用作基本临时目录{basetemp}/{testname}/请注意,在这种情况下没有保留功能:只保留最近一次运行的结果。
警告
提供给
--basetemp的目录将在每次测试运行前被盲目清除,因此请确保仅将该目录用于此目的。
当使用 pytest-xdist 在本地机器上分发测试时,会自动配置子进程的 basetemp 目录,以便所有临时数据都位于单个每次测试运行的临时目录下。