{"id":20056991,"url":"https://github.com/rhcarvalho/pytest-subprocess-example","last_synced_at":"2025-10-05T17:57:18.565Z","repository":{"id":66869481,"uuid":"220112018","full_name":"rhcarvalho/pytest-subprocess-example","owner":"rhcarvalho","description":"How to test interactive command line programs","archived":false,"fork":false,"pushed_at":"2019-11-07T18:15:32.000Z","size":4,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-06T19:05:27.616Z","etag":null,"topics":["pytest","python","subprocess","testing"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rhcarvalho.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-06T23:47:33.000Z","updated_at":"2025-04-16T16:04:40.000Z","dependencies_parsed_at":"2023-05-31T16:01:04.767Z","dependency_job_id":null,"html_url":"https://github.com/rhcarvalho/pytest-subprocess-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rhcarvalho/pytest-subprocess-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhcarvalho%2Fpytest-subprocess-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhcarvalho%2Fpytest-subprocess-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhcarvalho%2Fpytest-subprocess-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhcarvalho%2Fpytest-subprocess-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rhcarvalho","download_url":"https://codeload.github.com/rhcarvalho/pytest-subprocess-example/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhcarvalho%2Fpytest-subprocess-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278494624,"owners_count":25996414,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pytest","python","subprocess","testing"],"created_at":"2024-11-13T12:57:17.006Z","updated_at":"2025-10-05T17:57:18.557Z","avatar_url":"https://github.com/rhcarvalho.png","language":"Python","readme":"# pytest subprocess example\n\nThis example repository showcases how to test command line programs using\n[pytest](https://pytest.org) and\n[subprocess](https://docs.python.org/3/library/subprocess.html).\n\nNote that it can used to test any kind of program that read from *stdin* and\nwrite to *stdout*. In other words, it is not limited to testing Python programs.\n\nThe motivation for this example was a discussion in the [mailing list of the\nPython User Group\nAustria](https://pyug.at/pipermail/pyugat-discuss/2019-November/000409.html).\n\nIn summary, the technique demonstrated here is a rather straightforward use of\n`subprocess` to run a Python program within a test while specifying the contents\nof *stdin* and checking *stdout*, *stderr* and process return code.\n\n## The example exercise\n\nFrom https://www.practicepython.org/exercise/2014/01/29/01-character-input.html:\n\n\u003e Create a program that asks the user to enter their name and their age. Print\n\u003e out a message addressed to them that tells them the year that they will turn\n\u003e 100 years old.\n\n## Reproducing the exercise\n\nLook through the commits in this repository. Each commit tries to snapshot a\nstep of a [TDD](https://en.wikipedia.org/wiki/Test-driven_development) cycle,\nincluding fixing \"mistakes\" as we learn more.\n\nFor running the code, you will need Python 3. The steps below will help you\ncreate and activate a virtual environment where we install `pytest`:\n\n```\npython3 -m venv env\nsource env/bin/activate\npip install pytest\npytest\n```\n\nYou can try checking out commit by commit and running the tests to see what\nhappens.\n\nUse `git log --oneline` to see a brief list of commit hashes and subjects.\n\nUse `git checkout [hash]` to change into a given commit, replacing \"[hash]\" with\na value from the `git log` command above.\n\n## reusable_program_test.py and reusable_program.py\n\nThere is an alternative strategy that avoids using `subprocess`: instead, we\nfocus our testing in the parts of the program that have no side effects (e.g.\nreading from *stdin* and writing to *stdout*). These tests are much faster to\nrun and less error prone.\n\nWe then use our code as a library and add another layer on top of it that does\nthe interaction with the user by asking for values and then printing the result.\n\nAmong other benefits, this let's you easily reuse components of your code. For\nexample, there could be two alternative ways to interact with the program like a\ncommand line and a Web interface, while the core logic is shared.\n\n\u003c!--\n\n## Origin\n\nThis section is commented out because it is not directly necessary to understand\nthe example. In fact, it adds another level of complexity that might just add\nconfusion. Still, it is present here as a reference point.\n\nWhen I saw the discussion in the PYUGAT mailing list, I remembered a technique\nemployed in the Go standard library (see\nhttps://golang.org/search?q=GO_WANT_HELPER_PROCESS). I have known and used the\ntechnique since at least as long as 2016, as I could find [evidence in the\nCoding Dojo Brno\narchives](https://github.com/dojo-brno/dojo-brno/tree/master/2016/2016-10-13/hex).\n\nAt that time, I was probably inspired by the talk \"Advanced Testing with Go\" by\nMitchell Hashimoto:\n\n- Slides: https://speakerdeck.com/mitchellh/advanced-testing-with-go\n- Video: https://www.youtube.com/watch?v=yszygk1cpEc\n\n--\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhcarvalho%2Fpytest-subprocess-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frhcarvalho%2Fpytest-subprocess-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhcarvalho%2Fpytest-subprocess-example/lists"}