如何构造_pytest.pytester.Testdir

时间:2017-09-17 03:46:58

标签: python ipython pytest

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

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

在进行一些挖掘之后,当你使用pytester插件执行pytest时,似乎这是一个自动构建并作为参数发送到函数的魔法夹具。当我追踪那个类时,它会通过一些神奇的request param重新构建,其中代码在告诉你魔法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而不是通过命令行运行。我该如何制作其中一个?是否有一些我错过的文档使得如何做到这一点,并且似乎不那么混淆?

如果我想使用这样的东西,我的测试是否有一种方法可以让魔术testdir参数更加明确,所以下一个看着它的编码器不会拉他/她的头发像我一样出去?

1 个答案:

答案 0 :(得分:0)

经过多次痛苦,我已经想出了如何实例化一个夹具值。

    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是至关重要的,否则这将不会打印stdout,或者在IPython中运行时崩溃。

鉴于准系统配置和会话,下一步是手动加载您将要使用的任何夹具功能。这相当于手动调用插件通常为您处理的挂钩。我通过查看尝试在没有它们的情况下运行代码时获得的属性错误找到了这些。通常它只是由于session或config缺少必需的属性。可能有更好的方法去做(也就是通过插件自动)。

接下来,我们创建一个函数来请求我们感兴趣的特定夹具。由您决定这些名称是什么。最后,我们设置了一个虚拟模块/函数树结构和调用fillfixtures,它具有神奇功效。然后,funcargs包含准备使用的这些对象的字典。如果您期望一些拆卸功能,请小心。我不确定这是否涵盖了这一点,但我并不真正需要它,因为我正在做的事情。

希望这有助于其他人。注意:这个讲话让我更好地理解了pytest中发生的事情:https://www.youtube.com/watch?v=zZsNPDfOoHU