Click: Enable CliRunner to echo output to stdout/stderr

Created on 16 Feb 2017  路  1Comment  路  Source: pallets/click

I'm driving my CliRunner testing from pytest. pytest will capture stdout/stderr by default, and display them when an assertion fails. As CliRunner captures all of the output itself, I don't get any guidance as to what my application has done on failure, without adding explicit debugging code to each assertion.

I'd like to be able to do something like CliRunner(echo=True) so that I get the output of its run both in its attributes and actually written to stdout/stderr.

test runner

Most helpful comment

Would also love to see this.

I haven't dug deep into the internals for CliRunner.isolation() here, so I'm probably not doing this in the most correct way, but here's my workaround for anyone else interested:

import functools

import pytest


@pytest.fixture
def cli():
    """Yield a click.testing.CliRunner to invoke the CLI."""
    class_ = click.testing.CliRunner

    def invoke_wrapper(f):
        """Augment CliRunner.invoke to emit its output to stdout.

        This enables pytest to show the output in its logs on test
        failures.

        """
        @functools.wraps(f)
        def wrapper(*args, **kwargs):
            echo = kwargs.pop('echo', False)
            result = f(*args, **kwargs)

            if echo is True:
                sys.stdout.write(result.output)

            return result

        return wrapper

    class_.invoke = invoke_wrapper(class_.invoke)
    cli_runner = class_()

    yield cli_runner

...

def test_basic(cli, package):
    result = cli.invoke(package, ['--help])
    assert result.exit_code == 0

>All comments

Would also love to see this.

I haven't dug deep into the internals for CliRunner.isolation() here, so I'm probably not doing this in the most correct way, but here's my workaround for anyone else interested:

import functools

import pytest


@pytest.fixture
def cli():
    """Yield a click.testing.CliRunner to invoke the CLI."""
    class_ = click.testing.CliRunner

    def invoke_wrapper(f):
        """Augment CliRunner.invoke to emit its output to stdout.

        This enables pytest to show the output in its logs on test
        failures.

        """
        @functools.wraps(f)
        def wrapper(*args, **kwargs):
            echo = kwargs.pop('echo', False)
            result = f(*args, **kwargs)

            if echo is True:
                sys.stdout.write(result.output)

            return result

        return wrapper

    class_.invoke = invoke_wrapper(class_.invoke)
    cli_runner = class_()

    yield cli_runner

...

def test_basic(cli, package):
    result = cli.invoke(package, ['--help])
    assert result.exit_code == 0
Was this page helpful?
0 / 5 - 0 ratings