pytest-dev / pytest-dev/pytest

Using `capfd` in fixture breaks output capturing

Open
#4,428 11 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

plugin: capture topic: fixtures
Dominant language
Python
Stars
14.5k
Forks
3.4k
Avg merge
2d 9h
Merged PRs (30d)
35

Description

Consider the following code:

import sys
import subprocess
import pytest

#@pytest.yield_fixture(autouse=True)
#def does_nothing(request, capfd):
#   yield

@pytest.fixture(scope='function')
def emits_stdout():
    sub = subprocess.Popen([
        sys.executable,
        '-c', ';'.join((
            'import time',
            'print("hello world")',
            'time.sleep(0.5)',
            'print("hello whirled")',
        ))
    ])
    yield 'foo'
    sub.wait()

def test_something(emits_stdout):
    import time
    time.sleep(0.7)
    assert False

The output is as expected:

$ python3 -m pytest test_it.py 
==================================== test session starts =====================================
platform linux -- Python 3.5.3, pytest-3.8.0, py-1.6.0, pluggy-0.7.1
rootdir: /home/nikratio/tmp/tests, inifile:
plugins: trio-0.5.0
collected 1 item                                                                             

test_it.py F                                                                           [100%]

========================================== FAILURES ==========================================
_______________________________________ test_something _______________________________________

emits_stdout = 'foo'

    def test_something(emits_stdout):
        import time
        time.sleep(0.7)
>       assert False
E       assert False

test_it.py:27: AssertionError
------------------------------------ Captured stdout call ------------------------------------
hello world
hello whirled
================================== 1 failed in 0.73 seconds ==================================

However, if I uncomment the "noop" fixture, no output is captured anymore:

$ python3 -m pytest test_it.py 
==================================== test session starts =====================================
platform linux -- Python 3.5.3, pytest-3.8.0, py-1.6.0, pluggy-0.7.1
rootdir: /home/nikratio/tmp/tests, inifile:
plugins: trio-0.5.0
collected 1 item                                                                             

test_it.py F                                                                           [100%]

========================================== FAILURES ==========================================
_______________________________________ test_something _______________________________________

emits_stdout = 'foo'

    def test_something(emits_stdout):
        import time
        time.sleep(0.7)
>       assert False
E       assert False

test_it.py:27: AssertionError
================================== 1 failed in 0.75 seconds ==================================


Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the example in test_it.py with and without the no-op fixture using pytest's output-capturing tests and fixture handling as the entry points. Compare the captured output in both runs; done means the subprocess output remains available in the failure report when a fixture requests capfd.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.