click
click copied to clipboard
Enable CliRunner to echo output to stdout/stderr
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.
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
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