Skip to main content
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 https://img.shields.io/pypi/pyversions/clatter.svg

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_str = r'''
...
... .. code-block:: bash
...
...     $ echo 'Pining for the fjords'
...     Pining for the fjords
... '''
>>>
>>> tester = Runner()
>>> tester.call_engines['echo'] = SubprocessValidator()
>>> tester.teststring(test_str)

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_str = '''
...
... .. 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_str)

Mixed applications

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

>>> test_str = 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_str)

Suppressing commands

Commands can be skipped altogether with a SkipValidator:

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

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

>>> tester.teststring(test_str)

Illegal commands

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

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

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

Unrecognized commands will not raise an error if +SKIP is specified

>>> test_str = r'''
...
... .. code-block:: bash
...
...     $ nmake all # doctest: +SKIP
...     $ echo 'I made it!'
...     I made it!
...
... '''
>>> tester.teststring(test_str)

Error handling

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

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

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

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

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_str = '''
...    $ echo hello > test.txt
...    $ cat test.txt
...    hello
...
... '''
>>> tester.teststring(test_str) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
ValueError: Clatter test failed. hello > test.txt
 !=
+ hello > test.txt
-

Installation

pip install clatter

Requirements

  • pytest

Todo

See issues to see and add to our todos.

Metadata

Release files for clatter 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for clatter 0.1.1
File Size Uploaded
clatter-0.1.1.tar.gz 17.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for clatter 0.1.1
File Interpreter ABI Platform
clatter-0.1.1-py2.py3-none-any.whl Python 2, Python 3 none any Details

Total release size: 26.8 kB

Release files / clatter-0.1.1.tar.gz

Download URL clatter-0.1.1.tar.gz
Size 17.4 kB
Tags Source
SHA-256 checksum
How to use checksums
c43f4f9f297841b9159e99ebcc855960f910b953a79e8dd9afa8cbc8a7b071cf
BLAKE2b-256 checksum
How to use checksums
f5bf03ca35fe3bd7d47dfacde6618555c3e4672323bee6c16b157fc263eb2601
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / clatter-0.1.1-py2.py3-none-any.whl

Download URL clatter-0.1.1-py2.py3-none-any.whl
Size 9.3 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
e6dcda476297d505f3f62254fbdda2e46aed3be7f56979b258faa2a8fb96209a
BLAKE2b-256 checksum
How to use checksums
25a1e57a389060899a0e2e253f290b804211a8f6e1db1dcd8492938d69316ad3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page