Pytest如何获取当前测试文件的路径?

10

我似乎无法获取正在pytest测试的当前文件的文件路径。

例如,考虑以下目录结构:

devops_scripts
├── devops_utilities
│   ├── backupMonthly.py
│   ├── generateAnsibleINI.py
│   └── tests
│       └── test_backup.txt
├── monitoring
│   ├── analyizeCatalinaLog.py
│   ├── fetchCatalinaLogs.py
│   └── getaccountcredit.py
├── pi_provisioning
│   ├── piImageMake.sh
│   ├── piImageRead.sh
│   └── piImageSquashSd.py
└── script_utilities
    ├── README.md
    ├── __init__.py
    ├── execute.py
    ├── path_handling.py
    ├── sql_handling.py
    └── tests
        ├── sourcedirfortests
        │   ├── file1.txt
        │   └── file2.txt
        ├── test_ansible.txt
        └── test_execute.txt

如果我从顶层运行pytest,它会进入测试test_execute.txt。当test_execute.txt正在测试时,我如何获取文件路径?(我可以通过os.path.abspath('.')获取rootdir,但那不是我需要的)
(我需要能够设置这些路径以便在file1.txtfile2.txt上测试某些执行内容。我还需要让它在任何嵌套深度的情况下都能正常工作。)我对设置特定的临时测试目录并将其删除等操作不是很感兴趣。我只需要正在测试的文件的路径。
我尝试过以下方法:
>>> print os.path.abspath(__file__)

但只会产生如下结果:UNEXPECTED EXCEPTION: NameError("name '__file__' is not defined",)

我甚至可以访问py.test中的一些内部函数/对象

(我应该补充说明,我需要这在Python 2.7和Python 3.x中都能工作)


在 PY3.6 的 pytest 中,os.path.abspath(__file__) 对我来说可以正常解析。 - Stephen Rauch
2
__file__ 只在实际的 Python 文件中起作用,而不在交互式 shell 中。 - Lie Ryan
@StephenRauch 我应该补充说明,我需要在Python2.7中也能运行这个程序。 - Jason Harris
@JasonHarris,你认为__file__在Py2和Py3之间发生了变化吗? - Stephen Rauch
@StephenRauch 当我在pytest中尝试时,它不起作用:================== FAILURES ========== __________ [doctest] test_execute.txt _________ 006 >>> import sys 007 >>> print(os.path.abspath(__file__)) UNEXPECTED EXCEPTION: NameError("name 'file' is not defined") Traceback (most recent call last): File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/doctest.py", line 1329, in run compileflags, 1), test.globs) File "<doctest test_execute.txt[6]>", line 1, in <module> NameError: name '__file' is not defined - Jason Harris
2个回答

11

Pytest 为当前正在运行的测试设置 PYTEST_CURRENT_TEST 环境变量。它不仅包含当前文件的信息,还包括当前收集的测试 ID 的信息(例如测试名称、参数等)。

import os
def test_current():
    print(os.getenv('PYTEST_CURRENT_TEST'))

如果你想查看打印出的文本,必须在 pytest 运行时使用 -s 标志。

参考文档:Reference Doc

在测试会话期间,pytest 将 PYTEST_CURRENT_TEST 设置为当前测试节点 ID 和当前阶段(可以是 setup、call 或 teardown)。


1
哈利路亚!它可以了!!非常感谢你!(我删除了有关先前解决方案无法工作的旧评论) - Jason Harris
2
PYTEST_CURRENT_TEST的内容应该是易于人类阅读的,实际格式可能会在发布之间(甚至错误修复之间)更改,因此不应依赖于它进行脚本编写或自动化。 - Nick Veld
3
没问题,@NickVeld,你说得对。为了避免那种情况,应该使用“request”装置来获取当前正在运行的测试。应该使用“request.node”。 - SilentGuy

4

与接受的答案相反,请不要使用PYTEST_CURRENT_TEST环境变量。文档明确指出“不应依赖它”,而在这种情况下,它甚至不是原始问题所要求的内容,即“正在进行测试的当前文件路径”。

给定以下目录结构:

graph/
├── test/
│   └── __init__.py/
│       └── test_graph.py
├── __init__.py
└── functions.py

在文件test_graph.py中的函数test_bfs中,PYTEST_CURRENT_TEST的值为:
'graph/test/test_graph.py::test_bfs (call)'

鉴于request.path的值为graph/test/test_graph.py。这正是OP所要求的。
关于request: FixtureRequest的更多信息在这里

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接