如何以交互方式获得pytest夹具?

时间:2017-08-30 22:23:27

标签: python pytest

如何导入或以其他方式绑定pytest夹具以供交互使用,而不使用断点?

例如,我想探索REPL中tmpdir_factory fixture的一些行为。

from pytest import tmpdir_factory  # note: this doesn't actually work

# setup / context has already been entered
tmpdir_factory.ensure('exists.txt', file=True)  # I can use the fixture
del tmpdir_factory  # teardown will eventually be called

tmpdir的情况下,我已经知道它只是一个py.path.local实例,但我也对用户定义的灯具的一般问题感兴趣。

编辑:另一个可接受的界面:

from magical_module import inject_fixture
tmpdir_factory = inject_fixture('tmpdir_factory')

编辑:一个MCVE,用于显示上下文是否已退出:

# conftest.py
from datetime import datetime
import pytest

@pytest.fixture
def my_fixture():
    obj = {'setup': datetime.now()}
    yield (obj, f'yielded @ {datetime.now()!r}')
    obj['teardown'] = datetime.now()

2 个答案:

答案 0 :(得分:3)

Call IPython.embed() to drop into IPython's REPL,并使用request fixture's getfixturevalue()方法访问任意固定值

def test_stuff(request):
    from IPython import embed
    embed()

注意: pytest必须使用-s标记运行到disable capturing of stdout/stderr

$ pytest -s
============================= test session starts ==============================
platform linux -- Python 3.6.2, pytest-3.2.1, py-1.4.34, pluggy-0.4.0
rootdir: /home/they4kman/.virtualenvs/tmp-26171665bd77f5/src, inifile:
collected 1 item                                                                

test_stuff.py Python 3.6.2 (default, Jul 20 2017, 08:43:29) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: request.getfixturevalue('tmpdir_factory')
Out[1]: <_pytest.tmpdir.TempdirFactory at 0x7f71a7d501d0>

IPython must be installed,当然;)

答案 1 :(得分:2)

虽然某些灯具可在会话范围内使用,但没有灯具会在运行测试之前获得值。使用灯具最简单的方法是在测试功能中设置一个断点......但是我们可以通过一些hackery来绕过这个断点:

# magical_module.py
import pytest

_fixture_name = None
_fixture_value = None

def test_stuff(request):
    global _fixture_value
    fixturedef = request._get_active_fixturedef(_fixture_name)
    fixturedef._finalizer = []  # disable fixture teardown
    _fixture_value = fixturedef.cached_result[0]

def inject_fixture(fixturename):
    global _fixture_name
    _fixture_name = fixturename
    pytest.main(['-qq', __file__])
    return _fixture_value

然后您可以从REPL

访问它们
$ python
Python 3.6.2 (default, Jul 20 2017, 08:43:29) 
[GCC 5.4.1 20170519] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from magical_module import inject_fixture
>>> tmpdir_factory = inject_fixture('tmpdir_factory')
.
>>> tmpdir_factory
<_pytest.tmpdir.TempdirFactory object at 0x7fbf22df46a0>