Py.test No module named *

Learn py.test no module named * with practical examples, diagrams, and best practices. Covers python, pytest development techniques with visual explanations.

Resolving 'ModuleNotFoundError' in Pytest

Hero image for Py.test No module named *

Learn how to diagnose and fix the common 'ModuleNotFoundError' when running tests with Pytest, ensuring your Python test suite runs smoothly.

Encountering a ModuleNotFoundError when running your tests with Pytest can be a frustrating experience. This error typically means that Python cannot find one of the modules or packages that your test files or the code they are testing depend on. This article will guide you through the common causes of this error and provide practical solutions to get your Pytest suite back on track.

Understanding Python's Module Search Path

Before diving into solutions, it's crucial to understand how Python locates modules. When you import a module, Python searches for it in a specific order of locations defined in sys.path. This path includes:

  1. The directory containing the input script (or current working directory).
  2. PYTHONPATH (an environment variable).
  3. Standard library directories.
  4. The contents of any .pth files (site-packages).

Pytest, when executed, modifies sys.path to include the current working directory and potentially other relevant paths. However, if your project structure is complex or your tests are located in subdirectories, Pytest might not automatically discover all necessary paths, leading to ModuleNotFoundError.

flowchart TD
    A[Start Pytest] --> B{Python Interpreter}
    B --> C[Check sys.path]
    C --> D{Module Found?}
    D -- Yes --> E[Import Module]
    D -- No --> F[ModuleNotFoundError]
    F --> G[Troubleshoot: PYTHONPATH, Project Structure, __init__.py]

Simplified Python Module Import Flow

Common Causes and Solutions

The ModuleNotFoundError can stem from several issues. Here's a breakdown of the most frequent culprits and how to address them.

1. Incorrect Project Structure or Missing __init__.py

Python treats directories containing an __init__.py file as packages. If you're trying to import modules from a subdirectory that isn't recognized as a package, Python won't find them. Even an empty __init__.py file is sufficient to mark a directory as a Python package.

my_project/
├── src/
│   ├── __init__.py
│   └── my_module.py
└── tests/
    ├── __init__.py
    └── test_my_module.py

Example of a correct project structure with __init__.py files.

In this structure, test_my_module.py can import my_module using from src.my_module import ... because src is a package. If src/__init__.py were missing, src would just be a regular directory, and Python wouldn't know how to resolve src.my_module.

2. PYTHONPATH Not Set Correctly

The PYTHONPATH environment variable tells Python where to look for modules and packages. If your project's root directory (or a directory containing your modules) isn't on the PYTHONPATH, imports will fail. Pytest often handles this by adding the current directory to sys.path, but sometimes manual intervention is needed, especially when running tests from a different directory or with complex setups.

export PYTHONPATH=$PYTHONPATH:$(pwd)
pytest

Adding the current directory to PYTHONPATH before running Pytest.

Alternatively, you can add your project's root to sys.path programmatically within your test setup, though this is generally less recommended for maintainability.

3. Running Pytest from the Wrong Directory

Pytest's default behavior is to add the directory from which it's invoked to sys.path. If you run Pytest from a subdirectory, it might not be able to find modules located in parent directories or sibling directories that aren't explicitly part of a package structure.

# Incorrect: Running from 'tests' directory
cd my_project/tests
pytest

# Correct: Running from the project root
cd my_project
pytest

Demonstrating the impact of the current working directory on Pytest's module discovery.

4. Relative Imports in Top-Level Scripts

Relative imports (e.g., from . import my_module) are designed to work within packages. If you use a relative import in a script that's being run directly (not as part of a package import), Python won't know the package context, leading to an error. Ensure your test files use absolute imports relative to your project's root or package structure.

# In my_project/tests/test_my_module.py

# Incorrect relative import if 'tests' is not treated as a package
# from ..src.my_module import some_function

# Correct absolute import (assuming my_project is on PYTHONPATH or current dir)
from src.my_module import some_function

def test_something():
    assert some_function() == 'expected'

Using absolute imports for clarity and reliability in Pytest.

5. Typo in Module Name or File Name

This might seem obvious, but a simple typo in an import statement or the actual file name can cause a ModuleNotFoundError. Double-check your spelling and case sensitivity, especially on operating systems where file names are case-sensitive (like Linux).

6. Missing setup.py or pyproject.toml for Installable Packages

If your project is intended to be an installable package, having a setup.py or pyproject.toml file and installing it (e.g., pip install -e .) can help Pytest locate modules correctly. This effectively adds your package to Python's site-packages, making it discoverable.

pip install -e .

Installing your project in editable mode, making it discoverable by Pytest.

Debugging sys.path

When all else fails, inspecting sys.path directly can provide valuable clues. You can add a temporary print statement in your test file or a conftest.py to see what paths Python is currently searching.

# In your test file or conftest.py
import sys
print("\n--- sys.path ---")
for p in sys.path:
    print(p)
print("----------------")

# Your test code continues...

Printing sys.path to inspect Python's module search locations.

Look for the directory containing the module you're trying to import. If it's not listed, you've found your problem, and you can then apply one of the solutions above (e.g., adjusting PYTHONPATH or running Pytest from the correct directory) to add it.