I'm attempting to do some debugging (specifically on pytest/testing/test_doctest.py) and I want to step through some code in IPython. I have experience with pytest, but I never do anything too fancy with it, so I've never delved to deep into the more "magic" things it does.
In the test that I want to step through (potentially introspecting some of the objects), there is an argument called
def test_reportinfo(self, testdir):
Test case to make sure that DoctestItem.reportinfo() returns lineno.
p = testdir.makepyfile(test_reportinfo="""
items, reprec = testdir.inline_genitems(p, '--doctest-modules')
reportinfo = items.reportinfo()
assert reportinfo == 1
After much agonizing, I've figured out how to instantiate a fixture value.
import _pytest config = _pytest.config._prepareconfig(['-s']) 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']
The main idea is to create a dummy pytest session. This is a bit tricky. Its critical that the ['-s'] is passed into _prepareconfig otherwise this will not print stdout, or crash when run in IPython.
Given a barebones config and session, the next step is to manually load in whatever fixture functionality you are going to use. This amounts to manually calling the hooks that pluggy usually takes care of for you. I found these by looking at the attribute error I got when trying to run code without them. Usually its just due to session or config lacking a required attribute. There may be a better way to go about doing this (aka automatically via pluggy).
Next, we create a function that requests the specific fixture we are interested in. Its up to you to know what these names are. Finally we setup a dummy module / function tree structure and call fillfixtures, which does the magic. The funcargs then contains a dictionary of these objects ready for use. Be careful if you expect some teardown functionality. I'm not sure if this covers that, but I don't really need it for what I'm doing.
Hope this helps someone else. Note: this talk helped me understand what was happening in pytest under the hood a bit better: https://www.youtube.com/watch?v=zZsNPDfOoHU