Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

capsys fixture cannot be used with a session-scoped fixture #2704

Open
st-pasha opened this issue Aug 19, 2017 · 7 comments
Open

capsys fixture cannot be used with a session-scoped fixture #2704

st-pasha opened this issue Aug 19, 2017 · 7 comments
Labels
topic: fixtures anything involving fixtures directly or indirectly type: enhancement new feature or API change, should be merged into features branch type: feature-branch new feature or API change, should be merged into features branch

Comments

@st-pasha
Copy link

I have the following use-case: there is a class Auditor, which helps gather statistic about certain tests. This class is used via a fixture:

@pytest.fixture(scope="session")
def auditor():
    aud = Auditor()
    yield aud
    aud.display_summary()

The intention being that some tests would use this fixture, report their results to the Auditor singleton, and in the end of the testing session a report table is produced.

Unfortunately, currently this works only with -s flag, because otherwise all output is captured. Ideally I'd like to write the fixture function as

@pytest.fixture(scope="session")
def auditor(capsys):
    aud = Auditor()
    yield aud
    with capsys.disabled():
        aud.display_summary()

however doing so produces an error that capsys is a function-scope capture and cannot be used with a session-scope fixture.

I believe there should be a way to provide a session-scoped variant of capsys, so that it can be used from user-defined session-scoped fixtures.

@RonnyPfannschmidt RonnyPfannschmidt added type: enhancement new feature or API change, should be merged into features branch type: feature-branch new feature or API change, should be merged into features branch topic: fixtures anything involving fixtures directly or indirectly labels Aug 19, 2017
@RonnyPfannschmidt
Copy link
Member

while i also bevel there is a way, i'm reasonably certain that its not possible to do it sensible with the current capture system internals as such this one requires a larger internal rewrite

but i wouldn't mind to be shown wrong on this one

@st-pasha
Copy link
Author

I found that the following hack does the trick:

@pytest.fixture(scope="session")
def auditor():
    aud = Auditor()
    yield aud
    # The property `aud.capsys` is assigned in the test below
    with aud.capsys.disabled():
        aud.display_summary()

def test_fake(capsys, auditor):
    # This test doesn't test anything, but merely saves `capsys` fixture
    # as a property of the auditor.
    auditor.capsys = capsys

Of course, there is still the problem that test_fake may be skipped (if the user wants to run pytest on a subset of tests only).

@nicoddemus nicoddemus added type: enhancement new feature or API change, should be merged into features branch and removed type: enhancement new feature or API change, should be merged into features branch labels Sep 14, 2017
@L-F-Escobar
Copy link

This doesnt help me at all.

I have a session scoped function in conftest.py (root) which outputs data to the console for viewing. I have to pass the -s flag to see that data right now, but that produces tons of extra system data which pollutes the output.

I am attempting to pass capsys into the session scoped function but that produce a ScopeMismatch error.

Is there no way to print to console in a session scoped function without the -s command?

@tyll
Copy link

tyll commented Nov 19, 2019

I was missing this feature as well. I am using warnings.warn() now which might even be better in my use case. See nmstate/nmstate#588 for details if interested.

@miso-belica
Copy link

@tyll can you explain it more, please? From what I understand pytest captures the warnings too and shows them at the end but I would like to inform the user that some long-running process is running right away so he/she should be patient.

@RonnyPfannschmidt
Copy link
Member

https://pypi.org/project/pytest-print/ is a pytest plugin that provides a fixture which handles the details

@k4nar
Copy link
Contributor

k4nar commented Mar 24, 2020

I've found the following workaround, which seems to be working fine:

@pytest.fixture(scope=session)
def my_fixture(request):
    capmanager = request.config.pluginmanager.getplugin("capturemanager")

    ...

    with capmanager.global_and_fixture_disabled():
        print_something()

    ...

However if capsys could be a session fixture by default that would be much easier :) .

saschahauer pushed a commit to barebox/barebox that referenced this issue Aug 23, 2024
For trivial errors like a QEMU -bios or -kernel option not pointing at
an existing file, the pytest output is extremely confusing. It prints a
stack trace for every single test after QMPError("Received empty response")
is raised and the stderr text explaining that the file is missing is
easily overlooked.

Improve this by just existing right away once a strategy transition
fails and print the standard error if any as part of the exit message.

This looks a bit cumbersome, because the capsys fixture can't be used
with a session-scoped fixture, see the still open pytest issue[1] for
details.

[1]: pytest-dev/pytest#2704

Suggested-by: Bastian Krause <[email protected]>
Signed-off-by: Ahmad Fatoum <[email protected]>
Link: https://lore.barebox.org/[email protected]
Signed-off-by: Sascha Hauer <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: fixtures anything involving fixtures directly or indirectly type: enhancement new feature or API change, should be merged into features branch type: feature-branch new feature or API change, should be merged into features branch
Projects
None yet
Development

No branches or pull requests

7 participants