question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Using fixtures in the collection phase

See original GitHub issue

TL;DR: Is it possible to use the result of the doctest_namespace fixture in the collection phase? If not, what is the name of first hook after the autouse fixtures have been called?


I’m the maintainer of pytest-sphinx, which is a plugin that adds support for running tests defined in doctest related rst directives. Those directives are implemented in the sphinx.ext.doctest extension.

One cool feature of sphinx.ext.doctest is that directives can be skipped conditionally by specifying an option inside the body of the directive. Something like

.. testsetup::
   :skipif: pd is None

   data = pd.Series([42])

If the result of the skipif expression is a true value, the directive is omitted from the test run just as if it wasn’t present in the file at all.

In sphinx.ext.doctest the globals used for evaluating the skipif expressions are taken from the evaluation of the code in the doctest_global_setup configuration value (in conf.py), e.g.,

doctest_global_setup = """
    try:
        import pandas as pd
    except ImportError:
        pd = None
"""

Instead of evaluating a code-string in pytest-sphinx, I think it makes more sense to use pytest’s doctest_namespace fixture:

try:
     import pandas as pd
except ImportError:
     pd = None

@pytest.fixture(autouse=True)
def add_pd(doctest_namespace):
    doctest_namespace['pd'] = pd

How should pytest-sphinx handle the creation of test items in the following example?

.. testcode::
   :skipif: six.PY3

   data = pd.Series([42])

.. testcode::
   :skipif: six.PY2

   data = pd.Series([42])

.. testoutput::
   :skipif: six.PY3

   xxxxxx

.. testoutput::
   :skipif: six.PY2

   yyyyyy

Every testcode directive should be (regardless of whether the directive is skipped or not) part of a pytest.Item. Since the skipif expressions can’t be evaluated in the collection-phase AFAIK, the unskipped testoutput directive, belonging to the unskipped testcode directive, has to be determined as soon as the doctest-namespace is known. This is tricky, but probably it is doable, right?

Do you have a better idea for supporting the skipif option in pytest-sphinx? Probably it would be a lot easier if doctest-namespace were not used, because then we could evaluate the skipif expressions at collection-time.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:1
  • Comments:16 (16 by maintainers)

github_iconTop GitHub Comments

1reaction
SalmonModecommented, Jun 13, 2020

I don’t mean to gatekeep, and I feel like my ideal definition of fixtures falls within your own.

The distinction I draw is based in practicality. A test is only as good as it is repeatable. If your tests don’t know what they’re going to do before they start running, and they’re beholden to the state of the system as it already is, then they aren’t completely repeatable because they aren’t in control.

Pytest’s fixtures as they stand now, from my pov, are a perfect system for laying out the steps of a repeatable test, and for describing the resources those steps depend on. They describe the essence of what a given test is; not a series of steps to find out what tests can be done.

Again, that’s just my pov. My goal isn’t to force others to write tests a certain way. It’s to encourage them to write tests that are repeatable and in complete control of the SUT.

I’m not really gonna complain if such a feature as this is implemented, since I can just not use that feature. But I did want to throw my 2 cents out there.

1reaction
RonnyPfannschmidtcommented, Jun 13, 2020

This is simply for me, fixtures are a life cycle management and dependency injection system, its unavailability at collection time means people are forced to implement poor sidechannels

The only real reason they are not avaliable is how things initially grew, once runtestprotocol is broken down there are no more technical reasons not to do it

Read more comments on GitHub >

github_iconTop Results From Across the Web

About fixtures — pytest documentation
Fixtures define the steps and data that constitute the arrange phase of a test (see Anatomy of a test). In pytest, they are...
Read more >
Using fixtures at collect time in pytest - Stack Overflow
After reading a lot of source code I have came to conclusion, that it's impossible to call fixtures at collection time.
Read more >
End-To-End Tutorial For Pytest Fixtures With Examples
pytest fixtures are functions attached to the tests which run before the test function is executed. Fixtures are a set of resources that...
Read more >
Using Pytest Fixtures: A Step-by-Step Guide With Examples
In this step-by-step guide, we will go through a quick setup for Pytest with Fixtures and different types of fixtures.
Read more >
Simplify Your Tests With Fixtures - YouTube
Fixtures can make your tests simpler and easier to maintain by using or creating common abstractions to be shared amongst your tests.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found