Back to Repositories

Testing Python Module Error Correction Implementation in thefuck

This test suite validates the Python module error handling functionality in the thefuck command-line tool. It focuses on testing the automatic correction of missing Python module errors by suggesting pip install commands.

Test Coverage Overview

The test suite provides comprehensive coverage of Python module import error scenarios.

Key areas tested include:
  • Validation of module not found errors
  • Command correction suggestions for missing modules
  • Different script execution patterns (python script.py and ./script.py)
  • Edge cases with various module names and script paths

Implementation Analysis

The testing approach uses pytest’s parameterized testing to validate multiple scenarios efficiently.

Implementation features:
  • Fixture-based test data generation
  • Parameterized test cases for both positive and negative scenarios
  • Command object validation for input/output matching
  • Modular test organization with separate match and command generation tests

Technical Details

Testing infrastructure includes:
  • pytest as the primary testing framework
  • Custom Command type for input validation
  • Modular fixture system for error output generation
  • Parameterized test decorators for test case management

Best Practices Demonstrated

The test suite exemplifies several testing best practices.

Notable implementations:
  • Separation of concerns between matching and command generation
  • Comprehensive positive and negative test cases
  • Reusable test fixtures for consistent data
  • Clear test case organization and naming
  • Efficient test parameterization for multiple scenarios

nvbn/thefuck

tests/rules/test_python_module_error.py

            
import pytest

from thefuck.rules.python_module_error import get_new_command, match
from thefuck.types import Command


@pytest.fixture
def module_error_output(filename, module_name):
    return """Traceback (most recent call last):
  File "{0}", line 1, in <module>
    import {1}
ModuleNotFoundError: No module named '{1}'""".format(
        filename, module_name
    )


@pytest.mark.parametrize(
    "test",
    [
        Command("python hello_world.py", "Hello World"),
        Command(
            "./hello_world.py",
            """Traceback (most recent call last):
  File "hello_world.py", line 1, in <module>
    pritn("Hello World")
NameError: name 'pritn' is not defined""",
        ),
    ],
)
def test_not_match(test):
    assert not match(test)


positive_tests = [
    (
        "python some_script.py",
        "some_script.py",
        "more_itertools",
        "pip install more_itertools && python some_script.py",
    ),
    (
        "./some_other_script.py",
        "some_other_script.py",
        "a_module",
        "pip install a_module && ./some_other_script.py",
    ),
]


@pytest.mark.parametrize(
    "script, filename, module_name, corrected_script", positive_tests
)
def test_match(script, filename, module_name, corrected_script, module_error_output):
    assert match(Command(script, module_error_output))


@pytest.mark.parametrize(
    "script, filename, module_name, corrected_script", positive_tests
)
def test_get_new_command(
    script, filename, module_name, corrected_script, module_error_output
):
    assert get_new_command(Command(script, module_error_output)) == corrected_script