Skip to content

Instantly share code, notes, and snippets.

@reillysiemens
Last active July 19, 2017 04:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save reillysiemens/0cd29eedc5f4ecacae78bd95f7ef55b8 to your computer and use it in GitHub Desktop.
Save reillysiemens/0cd29eedc5f4ecacae78bd95f7ef55b8 to your computer and use it in GitHub Desktop.
Testing Click Applications with Pytest

Requirements

  • Python 3.6
  • pip
  • virtualenvwrapper

Instructions

Copy these files into a directory. Run the tests.

mkvirtualenv greet && pip install -e .'[dev]' && pytest -v
import sys
import click
@click.command()
@click.version_option()
@click.option('--count', default=1, show_default=True, help='Number of greetings')
@click.option('--name', prompt='Your name', help='The person to greet.')
@click.option('--debug', is_flag=True, show_default=True)
def cli(count: int, name: str, debug: bool) -> None:
if debug:
msg = f"[DEBUG] Printing greeting {count} times for {name}."
click.echo(msg, file=sys.stderr)
for _ in range(count):
click.echo(f"Hello, {name}!")
import os.path
from setuptools import setup, find_packages
from pip.req import parse_requirements
root = os.path.abspath(os.path.dirname(__file__))
req_path = os.path.join(root, 'requirements.txt')
reqs = [str(r.req) for r in parse_requirements(req_path, session=False)]
dev_req_path = os.path.join(root, 'dev-requirements.txt')
dev_reqs = [str(r.req) for r in parse_requirements(dev_req_path, session=False)]
setup(
name='greet',
version='0.1.0',
description='A greeter.',
author='Reilly Tucker Siemens',
packages=find_packages(),
include_package_data=True,
install_requires=reqs,
extras_require={
'dev': dev_reqs,
},
entry_points={
'console_scripts': [
'greet=greet:cli',
]
}
)
from click.testing import CliRunner
import pytest
import greet
def test_greet_no_options():
"""greet should prompt the user for their name given no options."""
runner = CliRunner()
result = runner.invoke(greet.cli, input='John Cleese')
assert not result.exception
assert result.output == 'Your name: John Cleese\nHello, John Cleese!\n'
@pytest.mark.parametrize('name', [
'',
'John Cleese',
'松本 人志',
'New\nLine',
])
def test_greet_with_name(name):
"""greet --name should not prompt for a name and use the given value."""
runner = CliRunner()
result = runner.invoke(greet.cli, ['--name', name])
assert result.output == f"Hello, {name}!\n"
@pytest.mark.parametrize('count', [
'-1',
'0',
'1',
'2',
'3',
'100',
])
def test_greet_with_count(count):
"""greet --count should output the greeting count times."""
runner = CliRunner()
result = runner.invoke(greet.cli, ['--count', count], input='John Cleese')
greetings = "Hello, John Cleese!\n" * int(count)
assert result.output == f"Your name: John Cleese\n{greetings}"
@pytest.mark.parametrize('name, count', [
('John Cleese', '5'),
('松本 人志', '10'),
])
def test_greet_with_name_and_count(name, count):
"""greet should work when given both --name and --count."""
runner = CliRunner()
result = runner.invoke(greet.cli, ['--name', name, '--count', count])
assert result.output == f"Hello, {name}!\n" * int(count)
def test_greet_shows_debug_info_in_debug_mode():
runner = CliRunner()
result = runner.invoke(greet.cli, ['--name', 'John Cleese', '--debug'])
assert result.output == ('[DEBUG] Printing greeting 1 times for John '
'Cleese.\nHello, John Cleese!\n')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment