如何动态更改 pytest 的 tmpdir 基本目录
How to Dynamically Change pytest's tmpdir Base Directory
根据 pytest documentation,可以按如下方式覆盖默认临时目录设置:
py.test --basetemp=/base_dir
然后在测试中使用 tmpdir
夹具时...
def test_new_base_dir(tmpdir):
print str(tmpdir)
assert False
...然后屏幕上会打印类似下面的内容:
/base_dir/test_new_base_dir_0
这按预期工作并且对于某些用例可能非常有用。
但是,我希望能够在每次测试(或者我应该说 "per-fixture")的基础上更改此设置。这种事情可能吗?
我即将在 code for the original 的基础上推出自己的 tmpdir
,但我宁愿不这样做——我想尽可能地在现有功能的基础上构建,而不是复制它。
顺便说一句,我的特殊用例是我正在编写一个 Python 模块,它将作用于不同类型的文件系统(NFS4 等),如果能够 yield 就好了tmpdir
的功能能够创建以下装置:
def test_nfs3_stuff(nfs3_tmpdir):
... test NFS3 functionality
def test_nfs4_stuff(nfs4_tmpdir):
... test NFS4 functionality
问题中提出的问题似乎没有很好的解决方案,所以我决定两次调用 py.test
:
- 为每个传递不同的
--basetemp
。
- 标记(使用
@pytest.mark.my_mark
)哪些测试需要使用非标准 basetemp 进行特殊处理。
- 将
-k my_mark
或 -k-my_mark
传递到每个调用中。
在 TempdirFactory
的源代码中,.config.option.basetemp
用作存储 basetemp
的属性。所以可以在使用前直接设置:
import pytest
import time
import os
def mktemp_db(tmpdir_factory, db):
basetemp = None
if 'PYTEST_TMPDIR' in os.environ:
basetemp = os.environ['PYTEST_TMPDIR']
if basetemp:
tmpdir_factory.config.option.basetemp = basetemp
if db == "db1.db":
tmpdb = tmpdir_factory.mktemp('data1_').join(db)
elif db == "db2.db":
tmpdb = tmpdir_factory.mktemp('data2_').join(db)
return tmpdb
@pytest.fixture(scope='session')
def empty_db(tmpdir_factory):
tmpdb = mktemp_db(tmpdir_factory, 'db1.db')
print("* " + str(tmpdb))
time.sleep(5)
return tmpdb
@pytest.fixture(scope='session')
def empty_db2(tmpdir_factory):
tmpdb = mktemp_db(tmpdir_factory, 'db2.db')
print("* " + str(tmpdb))
time.sleep(5)
return tmpdb
def test_empty_db(empty_db):
pass
def test_empty_db2(empty_db2):
pass
-
>set PYTEST_TMPDIR=./tmp
>python.exe -m pytest -q -s test_my_db.py
* c:\tests\tmp\data1_0\db1.db
.* c:\tests\tmp\data2_0\db2.db
.
2 passed in 10.03 seconds
根据 pytest documentation,可以按如下方式覆盖默认临时目录设置:
py.test --basetemp=/base_dir
然后在测试中使用 tmpdir
夹具时...
def test_new_base_dir(tmpdir):
print str(tmpdir)
assert False
...然后屏幕上会打印类似下面的内容:
/base_dir/test_new_base_dir_0
这按预期工作并且对于某些用例可能非常有用。
但是,我希望能够在每次测试(或者我应该说 "per-fixture")的基础上更改此设置。这种事情可能吗?
我即将在 code for the original 的基础上推出自己的 tmpdir
,但我宁愿不这样做——我想尽可能地在现有功能的基础上构建,而不是复制它。
顺便说一句,我的特殊用例是我正在编写一个 Python 模块,它将作用于不同类型的文件系统(NFS4 等),如果能够 yield 就好了tmpdir
的功能能够创建以下装置:
def test_nfs3_stuff(nfs3_tmpdir):
... test NFS3 functionality
def test_nfs4_stuff(nfs4_tmpdir):
... test NFS4 functionality
问题中提出的问题似乎没有很好的解决方案,所以我决定两次调用 py.test
:
- 为每个传递不同的
--basetemp
。 - 标记(使用
@pytest.mark.my_mark
)哪些测试需要使用非标准 basetemp 进行特殊处理。 - 将
-k my_mark
或-k-my_mark
传递到每个调用中。
在 TempdirFactory
的源代码中,.config.option.basetemp
用作存储 basetemp
的属性。所以可以在使用前直接设置:
import pytest
import time
import os
def mktemp_db(tmpdir_factory, db):
basetemp = None
if 'PYTEST_TMPDIR' in os.environ:
basetemp = os.environ['PYTEST_TMPDIR']
if basetemp:
tmpdir_factory.config.option.basetemp = basetemp
if db == "db1.db":
tmpdb = tmpdir_factory.mktemp('data1_').join(db)
elif db == "db2.db":
tmpdb = tmpdir_factory.mktemp('data2_').join(db)
return tmpdb
@pytest.fixture(scope='session')
def empty_db(tmpdir_factory):
tmpdb = mktemp_db(tmpdir_factory, 'db1.db')
print("* " + str(tmpdb))
time.sleep(5)
return tmpdb
@pytest.fixture(scope='session')
def empty_db2(tmpdir_factory):
tmpdb = mktemp_db(tmpdir_factory, 'db2.db')
print("* " + str(tmpdb))
time.sleep(5)
return tmpdb
def test_empty_db(empty_db):
pass
def test_empty_db2(empty_db2):
pass
-
>set PYTEST_TMPDIR=./tmp
>python.exe -m pytest -q -s test_my_db.py
* c:\tests\tmp\data1_0\db1.db
.* c:\tests\tmp\data2_0\db2.db
.
2 passed in 10.03 seconds