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

Enable CliRunner to echo output to stdout/stderr #737

Open
OddBloke opened this issue Feb 16, 2017 · 2 comments
Open

Enable CliRunner to echo output to stdout/stderr #737

OddBloke opened this issue Feb 16, 2017 · 2 comments
Labels
f:test runner feature: cli test runner

Comments

@OddBloke
Copy link

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.

@nguyening
Copy link

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

@mbirtwell
Copy link

I also came up against this. For the record my solution was the following helper method:

def invoke(cmd, expect_exit=0, catch_exceptions=False, **kwargs):
    runner = click.testing.CliRunner()
    result = runner.invoke(cli, cmd, catch_exceptions=catch_exceptions, **kwargs)
    if expect_exit is not None:
        assert result.exit_code == expect_exit
    return result

@pallets pallets deleted a comment from cornfeedhobo Jul 27, 2024
@pallets pallets temporarily blocked cornfeedhobo Jul 27, 2024
@pallets pallets deleted a comment from cornfeedhobo Jul 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
f:test runner feature: cli test runner
Projects
None yet
Development

No branches or pull requests

6 participants