Pytest plugin for testing console scripts

1.4.1 · active · verified Thu Apr 16

pytest-console-scripts is a pytest plugin designed for comprehensive testing of Python console scripts. It offers two execution modes: an 'in-process' mode for fast development iteration by running scripts within the same interpreter as pytest, and a 'subprocess' mode to simulate real-world execution environments. The library is actively maintained, with its latest version being 1.4.1, and typically follows a minor release cadence as needed for bug fixes and Python version support.

Common errors

Warnings

Install

Imports

Quickstart

To use `pytest-console-scripts`, define your console scripts in your project's `setup.py` (or `pyproject.toml`) and install your package in editable mode (`pip install -e .`). Then, in your pytest test files, use the `script_runner` fixture to execute your scripts and assert their output and exit codes. This example demonstrates creating a minimal project structure, installing it, and testing a console script using both default (in-process) and subprocess launch modes.

import pytest
import subprocess
import sys

# Create a dummy console script and setup.py for demonstration
# In a real project, these would exist in your project structure

# --- my_package/setup.py ---
# from setuptools import setup, find_packages
# setup(
#     name='my_package',
#     version='0.1.0',
#     packages=find_packages(),
#     entry_points={
#         'console_scripts': [
#             'my-script=my_package.main:main'
#         ]
#     },
# )

# --- my_package/main.py ---
# import sys
# def main():
#     if len(sys.argv) > 1 and sys.argv[1] == '--hello':
#         print('Hello from my-script')
#     else:
#         print('Running my-script')

# Simplified setup for a runnable quickstart within one file:
# Create dummy files for demonstration purposes
# A real setup would involve 'pip install -e .' in a virtual environment.

# Create a temporary directory and files
import tempfile
import os

def create_dummy_project(tmp_path):
    pkg_dir = tmp_path / "my_package"
    pkg_dir.mkdir()
    (pkg_dir / "__init__.py").touch()
    (pkg_dir / "main.py").write_text(
        """
import sys
def main():
    if len(sys.argv) > 1 and sys.argv[1] == '--hello':
        print('Hello from my-script')
    else:
        print('Running my-script')
    sys.exit(0)
"""
    )
    (tmp_path / "setup.py").write_text(
        """
from setuptools import setup, find_packages
setup(
    name='my_package',
    version='0.1.0',
    packages=find_packages(),
    entry_points={
        'console_scripts': [
            'my-script=my_package.main:main'
        ]
    },
)
"""
    )
    return tmp_path

# Example Test File (e.g., test_scripts.py)
def test_my_console_script(script_runner, tmp_path):
    # Set up the dummy project and install it in editable mode
    project_root = create_dummy_project(tmp_path)
    subprocess.run([sys.executable, '-m', 'pip', 'install', '-e', str(project_root)], check=True)

    # Run the script without arguments
    result = script_runner.run(['my-script'])
    assert result.returncode == 0
    assert 'Running my-script' in result.stdout
    assert result.stderr == ''

    # Run the script with an argument
    result_hello = script_runner.run(['my-script', '--hello'])
    assert result_hello.returncode == 0
    assert 'Hello from my-script' in result_hello.stdout
    assert result_hello.stderr == ''

    # Test behavior in subprocess mode (optional)
    result_subprocess = script_runner.run(['my-script'], launch_mode='subprocess')
    assert result_subprocess.returncode == 0
    assert 'Running my-script' in result_subprocess.stdout

view raw JSON →