Skip to main content
 首页 » 编程设计

python之让 pytest 在测试脚本的基本目录中查找

2025年05月04日37开发

在 pytest 中,我的测试脚本将计算结果与通过加载的基线结果进行比较

SCRIPTLOC = os.path.dirname(__file__) 
TESTBASELINE = os.path.join(SCRIPTLOC, 'baseline', 'baseline.csv') 
baseline = pandas.DataFrame.from_csv(TESTBASELINE) 

是否有一种非样板的方式告诉 pytest 从脚本的根目录开始查找而不是通过 SCRIPTLOC 获取绝对位置?

请您参考如下方法:

如果您只是在寻找与使用 __file__ 等效的 pytest,您可以将 request fixture 添加到您的测试中并使用 request.fspath

来自docs :

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) 

不过,如果您想避免样板文件,这样做不会有太大好处(假设我理解您所说的“非样板文件”是什么意思)

就我个人而言,我认为使用 fixture 更为明确(在 pytest 习语中),但我更喜欢将请求操作包装在另一个 fixture 中,因此我知道我只是通过查看的方法签名来专门获取示例测试数据一个测试。


这是我使用的一个片段(修改以匹配您的问题,我使用子目录层次结构):

# in conftest.py 
import pytest 
 
@pytest.fixture(scope="module") 
def script_loc(request): 
    '''Return the directory of the currently running test script''' 
 
    # uses .join instead of .dirname so we get a LocalPath object instead of 
    # a string. LocalPath.join calls normpath for us when joining the path 
    return request.fspath.join('..')  

和示例用法

def test_script_loc(script_loc): 
    baseline = script_loc.join('baseline/baseline.cvs') 
    print(baseline) 

更新:路径库

考虑到我早已停止支持旧版 Python,而是使用 pathlib,因此我不再返回 LocalPath 对象,也不依赖于它们的 API。 pytest 团队还计划最终弃用 py.path 和 port their internals to the standard library pathlib .这早在 pytest 3.9.0 就开始了,引入了 tmp_path,尽管 LocalPath 属性的实际删除可能在一段时间内不会发生。

虽然 pytest 团队可能会添加一个返回 Path 对象的替代属性(例如 request.fs_path ),但很容易将 LocalPath 转换为 现在我们自己。

这是使用 Path 对象的上述示例的变体,根据您的需要进行调整:

# in conftest.py 
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)