- 1. 相关的
fixture- 1.1.
tmp_path - 1.2.
tmp_path_factory - 1.3.
tmpdir - 1.4.
tmpdir_factory - 1.5. 区别
- 1.1.
- 2. 默认的基本临时目录
1. 相关的fixture
1.1. tmp_path
tmp_path是一个用例级别的fixture,其作用是返回一个唯一的临时目录对象(pathlib.Path);
我们看下面的例子:
# src/chapter-6/test_tmp_path.pyCONTENT = "content"def test_create_file(tmp_path):d = tmp_path / "sub" d.mkdir() # 创建一个子目录p = d / "hello.txt"p.write_text(CONTENT)assert p.read_text() == CONTENTassert len(list(tmp_path.iterdir())) == 1 # iterdir() 迭代目录,返回迭代器assert 0 # 为了展示,强制置为失败
执行:
λ pytest -q -s src/chapter-6/test_tmp_path.py
F
==================================== FAILURES =====================================
________________________________ test_create_file _________________________________tmp_path = WindowsPath('C:/Users/luyao/AppData/Local/Temp/pytest-of-luyao/pytest-4/test_create_file0')def test_create_file(tmp_path):d = tmp_path / "sub"d.mkdir() # 创建一个子目录p = d / "hello.txt"p.write_text(CONTENT)assert p.read_text() == CONTENTassert len(list(tmp_path.iterdir())) == 1 # iterdir() 迭代目录,返回迭代器
> assert 0 # 为了展示,强制置为失败
E assert 0src\chapter-6\test_tmp_path.py:32: AssertionError
1 failed in 0.06s
可以看出:
tmp_path在不同的操作系统中,返回的是不同类型的pathlib.Path对象,这里Windows系统下返回的是WindowsPath对象,它是Path的子类对象;Path对象可以使用/操作符代替常用的os.path.join()的方法;更多关于pathlib的使用方法可以查看:https://docs.python.org/3.7/library/pathlib.html
1.2. tmp_path_factory
tmp_path_factory是一个会话级别的fixture,其作用是在其它fixture或者用例中创建任意的临时目录;
查看上一章tmp_path fixture的源码,我们能够看到tmp_path就是使用tmp_path_factory的一个例子:
# _pytest.tmpdir@pytest.fixture
def tmp_path(request, tmp_path_factory):"""Return a temporary directory path objectwhich is unique to each test function invocation,created as a sub directory of the base temporarydirectory. The returned object is a :class:`pathlib.Path`object... note::in python < 3.6 this is a pathlib2.Path"""return _mk_tmp(request, tmp_path_factory)@pytest.fixture(scope="session")
def tmp_path_factory(request):"""Return a :class:`_pytest.tmpdir.TempPathFactory` instance for the test session."""return request.config._tmp_path_factory
可以看出:
-
tmp_path调用了tmp_path_factory; -
tmp_path_factory返回一个_pytest.tmpdir.TempPathFactory对象; -
进一步查看
_mk_tmp的源码:def _mk_tmp(request, factory):name = request.node.namename = re.sub(r"[\W]", "_", name)MAXVAL = 30name = name[:MAXVAL]return factory.mktemp(name, numbered=True)可以看出,
tmp_path最终调用了TempPathFactory.mktemp()方法,它返回的是一个pathlib.Path对象;
1.3. tmpdir
tmp_path是一个用例级别的fixture,其作用是返回一个唯一的临时目录对象(py.path.local),它提供os.path的方法;
上面的例子也可以修改成如下这样:
# src/chapter-6/test_tmpdir.pyCONTENT = "content"def test_create_file(tmpdir):p = tmpdir.mkdir("sub").join("hello.txt") # 创建子文件夹,并新建文件p.write(CONTENT)assert p.read() == CONTENTassert len(tmpdir.listdir()) == 1 # iterdir() 迭代目录,返回列表assert 0 # 为了展示,强制置为失败
执行:
λ pytest -q -s src/chapter-6/test_tmpdir.py
F
==================================== FAILURES =====================================
________________________________ test_create_file _________________________________
tmpdir = local('C:\\Users\\luyao\\AppData\\Local\\Temp\\pytest-of-luyao\\pytest-6\\test_create_file0')def test_create_file(tmpdir):p = tmpdir.mkdir("sub").join("hello.txt") # 创建子文件夹,并新建文件p.write(CONTENT)assert p.read() == CONTENTassert len(tmpdir.listdir()) == 1 # iterdir() 迭代目录,返回列表
> assert 0 # 为了展示,强制置为失败
E assert 0src\chapter-6\test_tmpdir.py:30: AssertionError
1 failed in 0.06s
其实,tmpdir也调用了tmp_path,只是对返回值做了一次py.path.local()封装:
# _pytest.tmpdir@pytest.fixture
def tmpdir(tmp_path):"""Return a temporary directory path objectwhich is unique to each test function invocation,created as a sub directory of the base temporarydirectory. The returned object is a `py.path.local`_path object... _`py.path.local`: https://py.readthedocs.io/en/latest/path.html"""return py.path.local(tmp_path)
1.4. tmpdir_factory
tmpdir_factory是一个会话级别的fixture,其作用是在其它fixture或者用例中创建任意的临时目录;
假设,一个测试会话需要使用到一个很大的由程序生成的图像文件,相比于每个测试用例生成一次文件,更好的做法是每个会话只生成一次:
import pytest@pytest.fixture(scope="session")
def image_file(tmpdir_factory):img = compute_expensive_image()fn = tmpdir_factory.mktemp("data").join("img.png")img.save(str(fn))return fndef test_histogram(image_file):img = load_image(image_file)# compute and test histogram
1.5. 区别
| fixture | 作用域 | 返回值类型 |
|---|---|---|
| tmp_path | 用例级别(function) | pathlib.Path |
| tmp_path_factory | 会话级别(session) | TempPathFactory |
| tmpdir | 用例级别(function) | py.local.path |
| tmpdir_factory | 会话级别(session) | TempDirFactory |
2. 默认的基本临时目录
上述fixture在创建临时目录时,都是创建在系统默认的临时目录(例如:Windows系统的%temp%目录)下;你可以通过指定--basetemp=mydir选项自定义默认的基本临时目录;
λ pytest -q -s --basetemp="/d/temp" src/chapter-6/test_tmpdir.py
F
==================================== FAILURES =====================================
________________________________ test_create_file _________________________________
tmpdir = local('D:\\temp\\test_create_file0')def test_create_file(tmpdir):p = tmpdir.mkdir("sub").join("hello.txt") # 创建子文件夹,并新建文件p.write(CONTENT)assert p.read() == CONTENTassert len(tmpdir.listdir()) == 1 # iterdir() 迭代目录,返回列表
> assert 0 # 为了展示,强制置为失败
E assert 0src\chapter-6\test_tmpdir.py:30: AssertionError
1 failed in 0.04s