Opened 4 years ago

Closed 4 years ago

#23930 closed New feature (fixed)

Add context managers for capturing output (testing utils)

Reported by: Wojtek Ruszczewski Owned by: nobody
Component: Testing framework Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Wojtek Ruszczewski)

I've recently written something like this (for #23929, where the output is generated by a signal handler):

@contextmanager
def capture_stdout():
    """
    Captures the ``sys.stdout`` stream, making anything written to it
    available in the stream returned as the manager's context.

    For example:

        with capture_stdout() as out:
            # Print something.
        self.assertIn("something", out.getvalue())
    """
    old_stdout = sys.stdout
    sys.stdout = out = StringIO()
    try:
        yield out
    finally:
        sys.stdout = old_stdout

Would it be better to make it public, leave it buried for the test only or don't bother testing the output in such cases at all?

Change History (9)

comment:1 Changed 4 years ago by Wojtek Ruszczewski

Description: modified (diff)

comment:2 Changed 4 years ago by Berker Peksag

What about stderr and stdin? CPython has similar helper functions for standard streams: https://hg.python.org/cpython/file/default/Lib/test/support/__init__.py#l1361

comment:3 Changed 4 years ago by Tim Graham

I am tempted to use those functions from Python although their use is discouraged: "The test package is meant for internal use by Python only. It is documented for the benefit of the core developers of Python. Any use of this package outside of Python’s standard library is discouraged as code mentioned here can change or be removed without notice between releases of Python."

We could easily copy them into Django if they went away at some point.

comment:4 Changed 4 years ago by Aymeric Augustin

test.support doesn't appear to be available on Python 2.

comment:5 Changed 4 years ago by Wojtek Ruszczewski

Description: modified (diff)

Thanks for the link, wasn't aware of the test.support module. It seems to be available for Python 2 also (at least captured_stdout()), but under a slightly different name test.test_support.

comment:6 Changed 4 years ago by Berker Peksag

It's test.test_support in Python 2. I don't think these helpers will go away soon, but it would be better to just copy them into django.test.utils. Also, some distributions may not include the test package in the default Python installation.

comment:7 Changed 4 years ago by Tim Graham

Summary: Context manager for capturing outputAdd context managers for capturing output (testing utils)
Triage Stage: UnreviewedAccepted

Okay, that is fine with me. I don't think we need to document them.

comment:8 Changed 4 years ago by Wojtek Ruszczewski

Has patch: set

The managers in the pull request were taken from the Mercurial's default branch, but those in the 2.7 branch differ only in the StreamIO import and comments.

comment:9 Changed 4 years ago by Tim Graham <timograham@…>

Resolution: fixed
Status: newclosed

In 6dbe979b4d9396e1b307c7d27388c97c13beb21c:

Fixed #23930 -- Added copies of captured_std* managers from CPython's test.support.

StringIO import was adapted for compatibility with Python 2.

Note: See TracTickets for help on using tickets.
Back to Top