Opened 9 years ago

Closed 9 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: dev
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 by Wojtek Ruszczewski, 9 years ago

Description: modified (diff)

comment:2 by Berker Peksag, 9 years ago

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 by Tim Graham, 9 years ago

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 by Aymeric Augustin, 9 years ago

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

comment:5 by Wojtek Ruszczewski, 9 years ago

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 by Berker Peksag, 9 years ago

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 by Tim Graham, 9 years ago

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 by Wojtek Ruszczewski, 9 years ago

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 by Tim Graham <timograham@…>, 9 years ago

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