Search code examples
pythonpython-click

Testing click with logging or return values instead of print


When I test click, I understand the basic setup looks something like this:

import click

@click.command()
@click.argument('name')
def hello(name):
   click.echo('Hello %s!' % name)

Test file

from click.testing import CliRunner
from hello import hello

def test_hello_world():
  runner = CliRunner()
  result = runner.invoke(hello, ['Peter'])
  assert result.exit_code == 0
  assert result.output == 'Hello Peter!\n'

However, if I use logging instead of print, I can't capture the output or check the return value of a command. For example:

import click
import logging as log

@click.command()
@click.argument('name')
def hello(name):
   log.info('Hello %s!' % name)
   return name

I can't check to see if that return value is correct without printing or click.echo'ing it.

Is there a way to check for return values or check output against logging using click?


Solution

  • You can use the caplog fixture in pytest to capture the logging output like this:

    def test_hello_world(caplog):
      runner = CliRunner()
      result = runner.invoke(hello, ['Peter'])
      assert result.exit_code == 0
      assert result.output == ''
      assert caplog.messages == ['Hello Peter!']
    

    As for wanting to check the "return" value of the command handler, Click decorated commands do not return anything in the conventional sense. The command itself uses the system return value, which is being tested here on the result.exit_code.

    If you really think you need to use the return value from the command handler, you can set the stand_alone flag.