Python 如何构造_pytest.pytester.Testdir的实例

Python 如何构造_pytest.pytester.Testdir的实例,python,ipython,pytest,Python,Ipython,Pytest,我正在尝试进行一些调试(特别是在pytest/testing/test_doctest.py上),我想逐步完成IPython中的一些代码。我有使用pytest的经验,但我从来没有用它做过太花哨的事情,所以我从来没有深入研究过它所做的更“神奇”的事情 在我想要逐步完成的测试中(可能会自省一些对象),有一个名为testdir的参数,但是在这个文件中没有任何地方引用什么是testdir,或者我如何可能构造一个 在做了一些挖掘之后,当您使用pytester插件执行pytest时,这似乎是一个神奇的装置,

我正在尝试进行一些调试(特别是在pytest/testing/test_doctest.py上),我想逐步完成IPython中的一些代码。我有使用pytest的经验,但我从来没有用它做过太花哨的事情,所以我从来没有深入研究过它所做的更“神奇”的事情

在我想要逐步完成的测试中(可能会自省一些对象),有一个名为
testdir
的参数,但是在这个文件中没有任何地方引用什么是
testdir
,或者我如何可能构造一个

在做了一些挖掘之后,当您使用
pytester
插件执行pytest时,这似乎是一个神奇的装置,它会自动构造并作为参数发送给您的函数。当我追踪到这个类时,它是通过一些magic
request
param再次构造的,在这里,代码在告诉你magic
request
是什么或者如何创建一个方面是毫无帮助的

为了使这个具体化,我只想做一个这样的测试:

def test_reportinfo(self, testdir):
    '''
    Test case to make sure that DoctestItem.reportinfo() returns lineno.
    '''
    p = testdir.makepyfile(test_reportinfo="""
        def foo(x):
            '''
                >>> foo('a')
                'b'
            '''
            return 'c'
    """)
    items, reprec = testdir.inline_genitems(p, '--doctest-modules')
    reportinfo = items[0].reportinfo()
    assert reportinfo[1] == 1
并在IPython中运行其逻辑。看看
testdir
对象的功能,它看起来很酷。它会自动为您生成一个文件,并有问题地运行pytest,而不是通过命令行。我怎么做一个呢?是否有一些我错过的文档,使如何做到这一点清楚,似乎不那么混乱


如果我想使用像这样的东西,这是我的测试,有没有一种方法可以让magic
testdir
参数稍微显化一点,这样下一个查看它的编码人员就不会像我一样拉扯头发了?

在经历了很多痛苦之后,我找到了如何实例化fixture值的方法

    import _pytest
    config = _pytest.config._prepareconfig(['-s'], plugins=['pytester'])
    session = _pytest.main.Session(config)
    _pytest.tmpdir.pytest_configure(config)
    _pytest.fixtures.pytest_sessionstart(session)
    _pytest.runner.pytest_sessionstart(session)

    def func(testdir):
        return testdir

    parent = _pytest.python.Module('parent', config=config, session=session)
    function = _pytest.python.Function(
        'func', parent, callobj=func, config=config, session=session)
    _pytest.fixtures.fillfixtures(function)
    testdir = function.funcargs['testdir']
其主要思想是创建一个虚拟pytest会话。这有点棘手。将['-s']传递到_prepareconfig中是至关重要的,否则这将不会打印标准输出,或者在IPython中运行时崩溃

给定一个基本配置和会话,下一步是手动加载您将要使用的任何装置功能。这相当于手动调用Plugy通常为您处理的钩子。我通过查看在尝试运行没有它们的代码时出现的属性错误找到了这些错误。通常是由于会话或配置缺少必需的属性。也许有更好的方法可以做到这一点(也就是通过pluggy自动完成)

接下来,我们创建一个函数来请求我们感兴趣的特定夹具。这取决于你知道这些名字是什么。最后,我们建立了一个虚拟的模块/函数树结构,并调用fillfixtures,这很神奇。funcargs然后包含这些对象的字典,可供使用。如果您期望一些拆卸功能,请小心。我不确定这是否包括这些,但我真的不需要它来做我正在做的事情


希望这对其他人有帮助。注意:这篇演讲帮助我更好地理解了pytest在幕后发生的事情:

在经历了许多痛苦之后,我已经找到了如何实例化fixture值的方法

    import _pytest
    config = _pytest.config._prepareconfig(['-s'], plugins=['pytester'])
    session = _pytest.main.Session(config)
    _pytest.tmpdir.pytest_configure(config)
    _pytest.fixtures.pytest_sessionstart(session)
    _pytest.runner.pytest_sessionstart(session)

    def func(testdir):
        return testdir

    parent = _pytest.python.Module('parent', config=config, session=session)
    function = _pytest.python.Function(
        'func', parent, callobj=func, config=config, session=session)
    _pytest.fixtures.fillfixtures(function)
    testdir = function.funcargs['testdir']
其主要思想是创建一个虚拟pytest会话。这有点棘手。将['-s']传递到_prepareconfig中是至关重要的,否则这将不会打印标准输出,或者在IPython中运行时崩溃

给定一个基本配置和会话,下一步是手动加载您将要使用的任何装置功能。这相当于手动调用Plugy通常为您处理的钩子。我通过查看在尝试运行没有它们的代码时出现的属性错误找到了这些错误。通常是由于会话或配置缺少必需的属性。也许有更好的方法可以做到这一点(也就是通过pluggy自动完成)

接下来,我们创建一个函数来请求我们感兴趣的特定夹具。这取决于你知道这些名字是什么。最后,我们建立了一个虚拟的模块/函数树结构,并调用fillfixtures,这很神奇。funcargs然后包含这些对象的字典,可供使用。如果您期望一些拆卸功能,请小心。我不确定这是否包括这些,但我真的不需要它来做我正在做的事情

希望这对其他人有帮助。注意:这次谈话帮助我更好地理解了pytest在引擎盖下发生的事情: