如果你只是想找到pytest中使用
__file__
的等效方法,你可以在测试中添加
request
fixture,并使用
request.path
。
来自
docs的内容:
class FixtureRequest
...
property path: Path
Path where the test function was collected.
所以一个例子可能是这样的:
def test_script_loc(request):
baseline = request.path.parent.joinpath('baseline', 'baseline.cvs')
print(baseline)
如果你想要避免模板代码,那么这样做对你来说并没有太多好处(假设我理解你所说的“非模板代码”是什么意思)。
就个人而言,我认为使用fixture更加明确(在pytest的习语中),但我更喜欢在另一个fixture中封装请求操作,这样我只需查看测试方法的方法签名,就能明确地知道我正在获取样本测试数据。
这是我使用的一小段代码(根据您的问题进行了修改,我使用了子目录层次结构):
import pytest
from pathlib import Path
@pytest.fixture(scope="module")
def script_loc(request):
'''Return the directory of the currently running test script'''
return request.path.parent
和示例用法
def test_script_loc(script_loc):
baseline = script_loc.joinpath('baseline/baseline.cvs')
print(baseline)
pytest <= 6 兼容性
我早就停止支持旧版的Python,而是使用pathlib
。
因此,我不再返回LocalPath
对象,也不依赖它们的API,但偶尔我仍然需要支持使用pytest<=6.0
的平台,这些平台尚未具备{{link1:request.path
属性}}。
pytest团队还计划最终弃用py.path
,并将其内部转移到标准库的pathlib
中{{link2:链接2}}。这一过程早在pytest 3.9.0中开始,引入了tmp_path
,但实际上删除LocalPath
属性可能需要一些时间。
在您可以升级到pytest>=7.0
之前,将LocalPath
转换为Path
非常容易。
以下是使用Path
对象的上述示例的变体,根据您的需要进行调整:
import pytest
from pathlib import Path
@pytest.fixture(scope="module")
def script_loc(request):
'''Return the directory of the currently running test script'''
return Path(request.fspath).parent
和示例用法
def test_script_loc(script_loc):
baseline = script_loc.joinpath('baseline/baseline.cvs')
print(baseline)
遗留的py.path
对于依赖于py.path
和/或需要Python 2.x支持的旧版本pytest,此答案的原始版本使用request.fspath
属性返回py.path.LocalPath
的实例。
来自文档:
class FixtureRequest
...
fspath
the file system path of the test module which collected this test.
所以一个例子可能是这样的:
def test_script_loc(request):
baseline = os.path.join(request.fspath.dirname, 'baseline', 'baseline.cvs')
print(baseline)
灯具的变种可能如下所示:
import pytest
@pytest.fixture(scope="module")
def script_loc(request):
'''Return the directory of the currently running test script'''
return request.fspath.join('..')
以及示例用法:
def test_script_loc(script_loc):
baseline = script_loc.join('baseline/baseline.cvs')
print(baseline)