https://github.com/rhcarvalho/pytest-subprocess-example
How to test interactive command line programs
https://github.com/rhcarvalho/pytest-subprocess-example
pytest python subprocess testing
Last synced: 3 months ago
JSON representation
How to test interactive command line programs
- Host: GitHub
- URL: https://github.com/rhcarvalho/pytest-subprocess-example
- Owner: rhcarvalho
- Created: 2019-11-06T23:47:33.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2019-11-07T18:15:32.000Z (about 6 years ago)
- Last Synced: 2025-06-06T19:05:27.616Z (7 months ago)
- Topics: pytest, python, subprocess, testing
- Language: Python
- Homepage:
- Size: 3.91 KB
- Stars: 4
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# pytest subprocess example
This example repository showcases how to test command line programs using
[pytest](https://pytest.org) and
[subprocess](https://docs.python.org/3/library/subprocess.html).
Note that it can used to test any kind of program that read from *stdin* and
write to *stdout*. In other words, it is not limited to testing Python programs.
The motivation for this example was a discussion in the [mailing list of the
Python User Group
Austria](https://pyug.at/pipermail/pyugat-discuss/2019-November/000409.html).
In summary, the technique demonstrated here is a rather straightforward use of
`subprocess` to run a Python program within a test while specifying the contents
of *stdin* and checking *stdout*, *stderr* and process return code.
## The example exercise
From https://www.practicepython.org/exercise/2014/01/29/01-character-input.html:
> Create a program that asks the user to enter their name and their age. Print
> out a message addressed to them that tells them the year that they will turn
> 100 years old.
## Reproducing the exercise
Look through the commits in this repository. Each commit tries to snapshot a
step of a [TDD](https://en.wikipedia.org/wiki/Test-driven_development) cycle,
including fixing "mistakes" as we learn more.
For running the code, you will need Python 3. The steps below will help you
create and activate a virtual environment where we install `pytest`:
```
python3 -m venv env
source env/bin/activate
pip install pytest
pytest
```
You can try checking out commit by commit and running the tests to see what
happens.
Use `git log --oneline` to see a brief list of commit hashes and subjects.
Use `git checkout [hash]` to change into a given commit, replacing "[hash]" with
a value from the `git log` command above.
## reusable_program_test.py and reusable_program.py
There is an alternative strategy that avoids using `subprocess`: instead, we
focus our testing in the parts of the program that have no side effects (e.g.
reading from *stdin* and writing to *stdout*). These tests are much faster to
run and less error prone.
We then use our code as a library and add another layer on top of it that does
the interaction with the user by asking for values and then printing the result.
Among other benefits, this let's you easily reuse components of your code. For
example, there could be two alternative ways to interact with the program like a
command line and a Web interface, while the core logic is shared.