Skip to content

[python] Migrate to Pytest#66

Open
hayat01sh1da wants to merge 4 commits intomasterfrom
hayat01sh1da/python/migrate-to-pytest
Open

[python] Migrate to Pytest#66
hayat01sh1da wants to merge 4 commits intomasterfrom
hayat01sh1da/python/migrate-to-pytest

Conversation

@hayat01sh1da
Copy link
Copy Markdown
Owner

1. Problem Overview

Running pytest . in the coding-tests/python directory produced 6 ModuleNotFoundError import failures:

ERROR collecting calculator_cli_app/test/queries/test_calculation_query.py
ERROR collecting calculator_cli_app/test/test_application.py
ERROR collecting fibonacci_sequence/test/test_fibonacci.py
ERROR collecting fizzbuzz/test/test_fizzbuzz.py
ERROR collecting letter_inspection/test/test_application.py
ERROR collecting nabeatsu/test/test_nabeatsu.py

2. Root Causes

  1. Incorrect Relative Paths: Test files used sys.path.append('./src') assuming execution from the project root, but pytest runs from individual test module directories
  2. Module Name Collisions: Multiple packages had identically named modules:
    • calculator_cli_app/src/application.py vs letter_inspection/src/application.py
    • calculator_cli_app/test/test_application.py vs letter_inspection/test/test_application.py
  3. Global sys.path Pollution: calculator_cli_app/src/application.py had global sys.path.append() statements that interfered with other modules
  4. Module Caching: Python's module cache reused previously imported modules with the same name, causing signature mismatches

3. Solutions Implemented

3-1. Fixed Import Paths in All Test Files

Updated 6 test files to use __file__-based absolute paths:

Files Updated:

  • calculator_cli_app/test/test_application.py
  • calculator_cli_app/test/queries/test_calculation_query.py
  • fibonacci_sequence/test/test_fibonacci.py
  • fizzbuzz/test/test_fizzbuzz.py
  • letter_inspection/test/test_letter_inspection_application.py
  • nabeatsu/test/test_nabeatsu.py

Pattern Applied:

test_dir = os.path.dirname(os.path.abspath(__file__))
module_root = os.path.dirname(test_dir)
src_path = os.path.join(module_root, 'src')

# Clear cached modules
for mod in list(sys.modules.keys()):
    if mod == 'application':
        del sys.modules[mod]

if src_path not in sys.path:
    sys.path.insert(0, src_path)

from application import Application

3-2. Added Module Cache Clearing

Before each import, cleared cached modules to prevent cross-module interference:

for mod in list(sys.modules.keys()):
    if mod == 'application':
        del sys.modules[mod]

This ensures each test imports the correct application.py from its own package directory.

3-3. Renamed Duplicate Test File

Renamed letter_inspection/test/test_application.py to letter_inspection/test/test_letter_inspection_application.py to avoid pytest module name collision.

3-4. Removed Global sys.path Modifications

Removed problematic code from calculator_cli_app/src/application.py:

# REMOVED:
import sys
sys.path.append('./calculator_cli_app/src')
sys.path.append('./calculator_cli_app/src/lib')
sys.path.append('./calculator_cli_app/src/queries')
sys.path.append('./calculator_cli_app/src/validations')

Dependencies are now handled through proper test-level sys.path management.

3-5. Added all Exports

Added explicit __all__ definitions to modules with wildcard imports:

  • fizzbuzz/src/fizzbuzz.py: __all__ = ['fizzbuzz_in_if', 'fizzbuzz_in_ternary']
  • nabeatsu/src/nabeatsu.py: __all__ = ['go_crazy_in_if', 'go_crazy_in_ternary']
  • fibonacci_sequence/src/fibonacci.py: __all__ = ['fibonacci']

3-6. Updated pyproject.toml

Added pytest configuration to properly handle module discovery:

[tool.pytest.ini_options]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]

4. Results

All 12 tests now pass successfully

calculator_cli_app/test/queries/test_calculation_query.py::TestArgumentZero::test_f_with_zero PASSED
calculator_cli_app/test/queries/test_calculation_query.py::TestArgumentTwo::test_f_with_two PASSED
calculator_cli_app/test/queries/test_calculation_query.py::TestArgumentFour::test_f_with_four PASSED
calculator_cli_app/test/test_application.py::TestApplication::test_run_success PASSED
fibonacci_sequence/test/test_fibonacci.py::TestCase1::test_fibonacci PASSED
fibonacci_sequence/test/test_fibonacci.py::TestCase2::test_fibonacci PASSED
fizzbuzz/test/test_fizzbuzz.py::TestIfStatement::test_fizzbuzz PASSED
fizzbuzz/test/test_fizzbuzz.py::TestTernaryStatement::test_fizzbuzz PASSED
letter_inspection/test/test_letter_inspection_application.py::TestRegularCase::test_exactly_equal_size_and_included_1 PASSED
letter_inspection/test/test_letter_inspection_application.py::TestCase1::test_exactly_equal_size_and_included_3 PASSED
nabeatsu/test/test_nabeatsu.py::TestIfStatement::test_go_crazy PASSED
nabeatsu/test/test_nabeatsu.py::TestTernaryStatement::test_go_crazy PASSED

12 passed in 4.24s

5. Key Takeaways

  • Always use __file__-based paths for test imports, not working directory-relative paths
  • Clear module cache when importing identically-named modules from different packages
  • Avoid global sys.path modifications in source files
  • Use explicit __all__ definitions for wildcard imports
  • Ensure unique test file names to prevent pytest module collision issues

@hayat01sh1da hayat01sh1da self-assigned this May 2, 2026
@hayat01sh1da hayat01sh1da force-pushed the hayat01sh1da/python/migrate-to-pytest branch from 53cfe8a to e4753c1 Compare May 2, 2026 19:37
@hayat01sh1da hayat01sh1da force-pushed the hayat01sh1da/python/migrate-to-pytest branch from c9872d0 to 5a47a48 Compare May 9, 2026 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant