{"id":4724,"library":"pytest-subprocess","title":"pytest-subprocess","description":"pytest-subprocess is a pytest plugin that allows faking the behavior of `subprocess` calls within tests, eliminating the need to rely on actual external processes. It hooks into `subprocess.Popen()` and consequently handles `subprocess.run()`, `subprocess.call()`, `subprocess.check_call()`, and `subprocess.check_output()` methods. The library is actively maintained with regular releases, ensuring compatibility and new features.","status":"active","version":"1.5.4","language":"en","source_language":"en","source_url":"https://github.com/aklajnert/pytest-subprocess","tags":["pytest","testing","mocking","subprocess"],"install":[{"cmd":"pip install pytest-subprocess","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"This is a pytest plugin and requires pytest to function.","package":"pytest","optional":false}],"imports":[{"note":"The `fake_process` fixture (or its alias `fp`) is automatically provided by the plugin to your test functions. No explicit import statement for the fixture itself is needed in your test file.","symbol":"fake_process","correct":"def test_something(fake_process):\n    # use fake_process here"}],"quickstart":{"code":"import subprocess\nimport pytest\n\ndef test_process_command(fp):\n    # Register a fake command and its expected output\n    fp.register(['fake-command'], stdout='Hello from fake-command')\n\n    # Run the command using subprocess (it will be faked by pytest-subprocess)\n    process = subprocess.run(['fake-command'], capture_output=True, text=True)\n\n    # Assert on the faked process's behavior\n    assert process.returncode == 0\n    assert process.stdout.strip() == 'Hello from fake-command'\n\ndef test_command_with_args(fp):\n    fp.register(['greet', 'world'], stdout='Greeting world!')\n    process = subprocess.run(['greet', 'world'], capture_output=True, text=True)\n    assert process.returncode == 0\n    assert process.stdout.strip() == 'Greeting world!'","lang":"python","description":"This example demonstrates how to use the `fp` (alias for `fake_process`) fixture to register a command and define its `stdout`. When `subprocess.run()` is called with the registered command, `pytest-subprocess` intercepts it and provides the faked output and return code."},"warnings":[{"fix":"Upgrade to `pytest-subprocess` 1.5.4 or newer. Alternatively, ensure explicit closing of `process.stdout`.","message":"On Python 3.12+, versions prior to 1.5.4 might lead to `ResourceWarning` for unclosed file handles when using `universal_newlines` or `text` arguments with `subprocess.Popen`.","severity":"gotcha","affected_versions":"<1.5.4"},{"fix":"Upgrade to `pytest-subprocess` 1.5.3 or newer to ensure correct timeout calculations.","message":"Older versions (prior to 1.5.3) contained an incorrect wait timeout calculation, which could lead to unreliable timeout behavior in tests.","severity":"gotcha","affected_versions":"<1.5.3"},{"fix":"Upgrade Python to 3.8+ on Windows, or convert `Path` objects to strings before passing them to `subprocess` commands.","message":"When running on Windows with Python versions prior to 3.8, passing `Path` objects as arguments to `subprocess` functions might result in a `TypeError`.","severity":"gotcha","affected_versions":">=1.5.0, Python < 3.8 on Windows"},{"fix":"Update tests to handle or expect exceptions from callbacks if you are upgrading from a version older than 1.4.2. Review callback implementations to ensure they behave as expected with the new error propagation.","message":"Prior to version 1.4.2, exceptions raised within callback functions passed to `register()` might have been silently ignored by `communicate()`. Version 1.4.2 changed this behavior to raise these exceptions, which could break tests relying on the silent failure.","severity":"breaking","affected_versions":"<1.4.2"},{"fix":"Explicitly register all commands you intend to fake. If you need to allow some commands to execute as real processes, use `fp.allow_unregistered(True)` or `fp.pass_command(['some-real-command'])`.","message":"By default, any attempt to run a `subprocess` command that has NOT been registered using `fp.register()` will raise a `ProcessNotRegisteredError`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure that `os.environ` or relevant `COV_*` environment variables are passed to the `env` argument of `subprocess.Popen` or `subprocess.run` calls within your tests. For example: `subprocess.run(command, env={**os.environ, **your_custom_env})`.","message":"When using `pytest-cov` to measure coverage of code run in subprocesses, `pytest-cov`'s environment variables must be explicitly passed to the subprocess. If these are not passed, coverage for the subprocess might not be collected.","severity":"gotcha","affected_versions":"All versions when combined with `pytest-cov`"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}