{"library":"pytest-xprocess","title":"pytest-xprocess: Pytest Plugin for External Process Management","description":"pytest-xprocess is a pytest plugin designed for robust management of external processes across test runs. It ensures that essential external processes, upon which an application depends, are started and properly terminated during pytest execution. The current version is 1.0.2, and the project maintains an active release cadence, with several updates per year, often coinciding with new Python or pytest versions.","language":"python","status":"active","last_verified":"Mon May 18","install":{"commands":["pip install pytest-xprocess"],"cli":{"name":"pytest","version":"pytest 9.0.3"}},"imports":["from xprocess import ProcessStarter","def my_fixture(xprocess):"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import pytest\nimport os\nimport time\n\n# This content would typically be in conftest.py\n# For demonstration, we'll create a dummy server script\n# and then use it in the quickstart.\n\ndummy_server_script = \"\"\"\n# dummy_server.py\nimport time\nimport sys\n\nif __name__ == '__main__':\n    print(\"Dummy server starting...\")\n    sys.stdout.flush()\n    time.sleep(1) # Simulate startup time\n    print(\"Dummy server ready on port 12345\")\n    sys.stdout.flush()\n    try:\n        while True:\n            time.sleep(0.5)\n    except KeyboardInterrupt:\n        print(\"Dummy server shutting down.\")\n        sys.stdout.flush()\n\"\"\"\n\n# Ensure the dummy server script exists for the quickstart to run\nwith open(\"dummy_server.py\", \"w\") as f:\n    f.write(dummy_server_script)\n\n@pytest.fixture(scope=\"session\")\ndef dummy_server(xprocess):\n    class Starter(xprocess.ProcessStarter):\n        # Path to the dummy server script\n        # Use absolute path to ensure it's found regardless of cwd\n        script_path = os.path.abspath(\"dummy_server.py\")\n        pattern = \"Dummy server ready on port 12345\"\n        args = [\"python\", script_path]\n\n        # Optional: increase timeout if the server takes longer to start\n        # timeout = 5 # Default is 120 seconds\n\n    # Ensure the process is running; get its logfile and info object\n    logfile = xprocess.ensure(\"dummy_server\", Starter)\n    \n    # You can interact with the server here if needed, e.g., check its status\n    # process_info = xprocess.getinfo(\"dummy_server\")\n    # assert process_info.isrunning()\n    \n    print(f\"\\nDummy server log: {logfile.name}\")\n    \n    # Yield control to the tests that depend on this fixture\n    yield logfile\n\n    # xprocess automatically handles termination after tests, but you can\n    # also get the info object and terminate manually if needed.\n    # xprocess.getinfo(\"dummy_server\").terminate()\n\ndef test_server_is_up(dummy_server):\n    # The dummy_server fixture ensures the server is running.\n    # You can read its log for verification or perform other checks.\n    with open(dummy_server.name, \"r\") as f:\n        logs = f.read()\n    assert \"Dummy server ready on port 12345\" in logs\n    print(\"Test: Dummy server is confirmed ready!\")\n\n# To run this, save as a .py file (e.g., test_quickstart.py) and run `pytest -s`\n# The -s flag is important to see print statements from the fixture and tests.\n","lang":"python","description":"This quickstart demonstrates how to define a process fixture using `pytest-xprocess` in a `conftest.py` file. It sets up a simple dummy server, waits for a specific pattern in its output to confirm readiness, and then allows tests to run against it. The `xprocess.ensure()` method guarantees the process is started and managed, including automatic cleanup after the test session.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-18","installed_version":"1.0.2","pypi_latest":"1.0.2","is_stale":false,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":2.9,"avg_import_s":0.06,"wheel_type":"wheel"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"pytest-xprocess","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.04,"mem_mb":1.9,"disk_size":"31.4M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"pytest-xprocess","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.9,"import_time_s":0.03,"mem_mb":1.9,"disk_size":"32M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"pytest-xprocess","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.1,"mem_mb":2.2,"disk_size":"34.5M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"pytest-xprocess","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.8,"import_time_s":0.09,"mem_mb":2.2,"disk_size":"35M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"pytest-xprocess","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.07,"mem_mb":2.2,"disk_size":"26.1M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"pytest-xprocess","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.6,"import_time_s":0.08,"mem_mb":2.2,"disk_size":"27M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"pytest-xprocess","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.07,"mem_mb":2.3,"disk_size":"25.9M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"pytest-xprocess","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.6,"import_time_s":0.08,"mem_mb":2.1,"disk_size":"26M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"pytest-xprocess","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.04,"mem_mb":1.8,"disk_size":"30.8M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"pytest-xprocess","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":3.4,"import_time_s":0.04,"mem_mb":1.8,"disk_size":"31M"}]}}