我正在使用 Pytest 夹具来清理测试期间创建的临时文件和目录。该装置适用于大多数测试用例,但无法完全删除前两个参数化测试中创建的目录。这是简化的装置:
import pytest
import os
import shutil
@pytest.fixture(scope="session")
def cleanup_environment():
temp_paths = [] # List to track temporary paths
yield temp_paths # Provide the list to tests
# Sort paths by directory depth (deepest first)
temp_paths_sorted = sorted(temp_paths, key=lambda p: p.count(os.sep), reverse=True)
for temp_path in temp_paths_sorted:
if os.path.exists(temp_path):
try:
if os.path.isfile(temp_path):
os.remove(temp_path)
elif os.path.isdir(temp_path):
shutil.rmtree(temp_path, ignore_errors=True)
except Exception as e:
print(f"Failed to remove {temp_path}: {e}")
for temp_path in temp_paths_sorted:
parent_dir = os.path.dirname(temp_path)
while parent_dir and os.path.exists(parent_dir) and not os.listdir(parent_dir):
try:
os.rmdir(parent_dir)
parent_dir = os.path.dirname(parent_dir)
except Exception as e:
print(f"Failed to remove parent directory {parent_dir}: {e}")
break
以下是测试用例:
def test_create_and_delete_file(cleanup_environment, tmpdir):
temp_file = tmpdir.join("temp_file.txt")
temp_file.write("Temporary content")
cleanup_environment.append(str(temp_file))
assert temp_file.check(file=True)
def test_create_and_delete_dir(cleanup_environment, tmpdir):
temp_dir = tmpdir.mkdir("temp_dir")
cleanup_environment.append(str(temp_dir))
assert temp_dir.check(dir=True)
@pytest.mark.parametrize("test_case", ["case1", "case2"])
def test_parameterized_cases(cleanup_environment, tmpdir, test_case):
temp_dir = tmpdir.mkdir(f"temp_dir_{test_case}")
cleanup_environment.append(str(temp_dir))
assert temp_dir.check(dir=True)
在参数化测试用例(
case1
和case2
)中,创建的目录并未完全删除,即使它们被附加到cleanup_environment
。
如何确保所有目录(包括参数化测试中的目录)都得到正确清理?
您为什么要费心跟踪这样的单个文件和/或目录?为每个会话创建一个临时目录,然后在完成后将其完全删除会更有意义。如果您使用自己的固定装置创建临时目录,而不是 pytest
tmpdir
固定装置(它被明确设计为在测试后不清理,以便您可以在测试运行完成后检查测试工件,那么这很容易).
类似这样的:
import pytest
import tempfile
from pathlib import Path
@pytest.fixture(scope="session")
def clean_tmpdir():
# a tempfile.TemporaryDirectory() object deletes itself when it
# goes out of scope.
with tempfile.TemporaryDirectory() as tmpdir:
yield Path(tmpdir)
@pytest.mark.parametrize("test_case", ["case1", "case2"])
def test_parameterized_cases(clean_tmpdir: Path, test_case: str):
print(f"using directory: {clean_tmpdir}")
dir = clean_tmpdir / f"temp_dir_{test_case}"
dir.mkdir()
assert dir.is_dir()