Skip to main content

A Doctest-stype Command Line Application Tester

Project description

https://img.shields.io/pypi/v/clatter.svg https://travis-ci.org/delgadom/clatter.svg?branch=master https://coveralls.io/repos/github/delgadom/clatter/badge.svg?branch=master Documentation Status Updates https://api.codacy.com/project/badge/Grade/2c2af36490c04543b925edafc0d66842

clatter is a doctest-style testing tool for command-line applications. It wraps other testing suites and allows them to be tested in docstrings.

Features

  • Bring testing best practices to your command line apps

  • Extensible - subclassing CommandValidator is trivial using any cli testing suite

  • Easily test your documentation. This README is a valid doctest!

Usage

>>> from clatter import Runner
>>> from clatter.validators import SubprocessValidator

Test command line utilities and applications by whitelisting them with app-specific testing engines:

>>> test_string = r'''
...
... .. code-block:: bash
...
...     $ echo 'Pining for the fjords'
...     Pining for the fjords
... '''
>>>
>>> tester = Runner()
>>> tester.call_engines['echo'] = SubprocessValidator()
>>> tester.teststring(test_string)

Click applications

Integrate your command line app:

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

This can now be tested in docstrings:

>>> test_string = '''
...
... .. code-block:: bash
...
...     $ hello Polly
...     Hello Polly!
...
...     $ hello Polly Parrot
...     Usage: hello [OPTIONS] NAME
...     <BLANKLINE>
...     Error: Got unexpected extra argument (Parrot)
...
...     $ hello 'Polly Parrot'
...     Hello Polly Parrot!
...
... '''

Click applications can be tested with a ClickValidator engine:

>>> from clatter.validators import ClickValidator
>>> tester = Runner()
>>> tester.call_engines['hello'] = ClickValidator(hello)

>>> tester.teststring(test_string)

Mixed applications

Your app can be combined with other command-line utilities by adding multiple engines:

>>> test_string = r'''
...
... .. code-block:: bash
...
...     $ hello Polly
...     Hello Polly!
...
...     $ echo 'Pining for the fjords'
...     Pining for the fjords
...
... Pipes/redirects don't work, so we can't redirect this value into a file.
... But we can write a file with python:
...
... .. code-block:: bash
...
...     $ python -c \
...     >     "with open('tmp.txt', 'w+') as f: f.write('Pushing up daisies')"
...
...     $ cat tmp.txt
...     Pushing up daisies
...
... '''

>>> tester.call_engines['echo'] = SubprocessValidator()
>>> tester.call_engines['python'] = SubprocessValidator()
>>> tester.call_engines['cat'] = SubprocessValidator()

>>> tester.teststring(test_string)

Suppressing commands

Commands can be skipped altogether with a SkipValidator:

>>> test_string = '''
... .. code-block:: bash
...
...     $ aws storage buckets list
...
... '''

>>> from clatter.validators import SkipValidator
>>> tester.call_engines['aws'] = SkipValidator()

>>> tester.teststring(test_string)

Illegal commands

Errors are raised when using an application you haven’t whitelisted:

>>> test_string = '''
...
... The following block of code should cause an error:
...
... .. code-block:: bash
...
...     $ rm tmp.txt
...
... '''

>>> tester.teststring(test_string) # doctest +ELLIPSIS
Traceback (most recent call last):
...
ValueError: Command "rm" not allowed. Add command caller to call_engines to whitelist.

Unrecognized commands will raise an error, even if +SKIP is specified

>>> test_string = '''
...
... .. code-block:: bash
...
...     $ nmake all
...
... '''
>>> tester.teststring(test_string) # doctest +ELLIPSIS
Traceback (most recent call last):
...
ValueError: Command "nmake" not allowed. Add command caller to call_engines to whitelist.

Error handling

Lines failing to match the command’s output will raise an error

>>> test_string = r'''
... .. code-block:: bash
...
...     $ echo "There, it moved!"
...     "No it didn't!"
...
... '''

>>> tester = Runner()
>>> tester.call_engines['echo'] = SubprocessValidator()

>>> tester.teststring(test_string) # doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: Clatter test failed. There, it moved!
 != "No it didn't!"
<BLANKLINE>
<BLANKLINE>
+ There, it moved!
<BLANKLINE>
- "No it didn't!"
<BLANKLINE>

Known issues

We have issues on our issues page. But we want to be very up-front about these.

Security

Similar to doctest, executing arbitrary commands from within your tests is dangerous, and we make no attempt to protect you. We won’t run commands you don’t whitelist, but we cant’t prevent against malicious cases. Don’t run anything you don’t understand, and use at your own risk.

Syntactic completeness

Clatter is not a syntactically complete bash emulator and has no intention of being so.

All arguments to commands are passed as arguments to the first command. Therefore, loops, pipes, redirects, and other control-flow and IO commands will not work as expected.

>>> test = '''
...    $ echo hello > test.txt
...    $ cat test.txt
...    hello
...
... '''
>>> tester.teststring(test) # doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: Clatter test failed. hello > test.txt
 !=

+ hello > test.txt

- blah

Installation

pip install clatter

Requirements

  • pytest

Todo

See issues to see and add to our todos.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

clatter-0.0.4.tar.gz (22.0 kB view details)

Uploaded Source

Built Distribution

clatter-0.0.4-py2.py3-none-any.whl (9.0 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file clatter-0.0.4.tar.gz.

File metadata

  • Download URL: clatter-0.0.4.tar.gz
  • Upload date:
  • Size: 22.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for clatter-0.0.4.tar.gz
Algorithm Hash digest
SHA256 f948086eb84e32cf331d9075dab44cc9c5f68c309188aa4a20ff6bf67854cea6
MD5 5b1a06225fd5fb02c84e913fe04d1a6a
BLAKE2b-256 eb4d0cf1bc4747271937d79976841aee3073aa39130e2d5cc9aaeb55684812e4

See more details on using hashes here.

File details

Details for the file clatter-0.0.4-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for clatter-0.0.4-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 28518330cc368254b654d227d2d7a4e68b299809f9aa373df5a3178ed73512c6
MD5 ebb80214a9fe2add1fcddf6ba722cad2
BLAKE2b-256 a4b5f6cb9d1c7302caa724678d6be8435b087b2cb823b129447d1cb7a535aea1

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page