what is a module?

A Python module is any file that ends in .py. Any folder that contains an __init__.py is also a Python module.


preview

I have these tests by the end of the chapter

module_not_found_error/tests/test_module_not_found_error.py
 1import src.module_00
 2import src.module_01
 3import src.module_02
 4import src.module_03
 5import src.module_04
 6import src.module_05
 7import src.doe
 8import src.doe.john
 9import src.doe.jane
10import magic
11
12
13# Exceptions seen
14# AssertionError
15# ModuleNotFoundError

start the project

  • I name this project module_not_found_error

  • I open a terminal

  • I change directory to the module_not_found_error project in the pumping_python folder

    cd module_not_found_error
    

    the terminal shows

    cd: no such file or directory: module_not_found_error
    

    there is no folder with the name module_not_found_error in this folder.

  • I use the uv Python Package Manager to setup the project

    uv init module_not_found_error
    

    the terminal shows

    Initialized project `module-not-found-error`
    at `.../pumping_python/module_not_found_error`
    
  • I change directory to the module_not_found_error folder

    cd module_not_found_error
    

    the terminal shows

    .../pumping_python/module_not_found_error
    
  • I make a child folder to keep the tests separate from the other files

    mkdir tests
    

    the terminal goes back to the command line.

  • I add an empty file to the tests folder

    touch tests/module_not_found_error.py
    
    New-Item tests/module_not_found_error.py
    
  • I open module_not_found_error.py from the tests folder

    Tip

    I can open a file from the terminal with ctrl (Windows/Linux) or command (MacOS) on the keyboard and a click with the mouse on the name of the file

  • I add the first failing test to module_not_found_error.py in the tests folder

    1assert False is True
    
  • I use the unittest module to run tests

    python3 -m unittest
    
    python -m unittest
    

    the terminal shows

    ------------------------------------------------------
    Ran 0 tests in 0.000s
    
    NO TESTS RAN
    
  • I close module_not_found_error.py

    Danger

    if you do not close module_not_found_error.py, there will be 3 files in the tests folder after the next step (instead of 2), because the Auto Save feature (enabled earlier) will save the original file if it is still open after you change its name.

  • I change the name of module_not_found_error.py in the tests folder to test_module_not_found_error.py

    mv tests/module_not_found_error.py \
    tests/test_module_not_found_error.py
    
    Move-Item tests/module_not_found_error.py \
    tests/test_module_not_found_error.py
    

    the terminal goes back to the command line.

    Tip

    The \ + enter/return allows me to write one long line on multiple lines in the terminal. Without it I have to write everything as one line because the terminal runs whatever line I have written when I hit enter/return on the keyboard.

  • I try to run the test again

    python3 -m unittest
    
    python -m unittest
    

    the terminal still shows NO TESTS RAN.

Danger

use 2 underscores (__) before and after init for __init__.py not _init_.py

  • I make the tests directory a Python package

    touch tests/__init__.py
    
  • I try to run the test again

    python3 -m unittest
    
  • I make the tests directory a Python package

    New-Item tests/__init__.py
    
  • I try to run the test again

    python -m unittest
    

the terminal is my friend, and shows AssertionError

...
  File ".../pumping_python/module_not_found_error/tests/test_module_not_found_error.py",
    line 1, in <module>
    assert False is True
            ^^^^^^^^^^^^^
AssertionError


------------------------------------------------------
Ran 1 test in X.YZs

FAILED (errors=1)
  • I hold ctrl (Windows/Linux) or option/command (MacOS) on the keyboard and use the mouse to click on File ".../pumping_python/module_not_found_error/tests/test_module_not_found_error.py", line 1 in the terminal, and the Integrated Development Environment (IDE) opens the file with the cursor at the line where the failure happened.

  • I add AssertionError to the list of Exceptions seen, in test_module_not_found_error.py

    1assert False is True
    2
    3
    4# Exceptions seen
    5# AssertionError
    
  • I change True to False

    1# assert False is True
    2assert False is False
    3
    4
    5# Exceptions seen
    6# AssertionError
    
  • I run the test again

    python3 -m unittest
    
    python -m unittest
    

    the test passes.

  • I add the new files and folders to git for tracking

    git add .
    

    the terminal goes back to the command line.

  • I add a git commit message

    git commit --all --message \
    'setup project'
    

    the terminal shows a summary of the changes then goes back to the command line. Time to test modules.


test_module_not_found_error

RED: make it fail


  • I remove the assert statements then add an import statement for a module at the top of the file

    1import src.module_00
    2
    3
    4# Exceptions seen
    5# AssertionError
    
  • I run the test again

    python3 -m unittest
    
    python -m unittest
    

    the terminal is my friend, and shows ModuleNotFoundError

      File ".../pumping_python/module_not_found_error/
                tests/test_module_not_found_error.py",
        line 1, in <module>
        import src.module_00
    ModuleNotFoundError: No module named 'src.module_00'
    
    
    ----------------------------------------------------------------------
    Ran 1 test in X.YZAs
    
    FAILED (errors=1)
    

    because when import src.module_00 runs, Python tries to bring in an object (everything in Python is an object) for the module_00.py file from the src folder.

  • I add ModuleNotFoundError to the list of Exceptions seen, in test_module_not_found_error.py

    4# Exceptions seen
    5# AssertionError
    6# ModuleNotFoundError
    

what causes ModuleNotFoundError?

ModuleNotFoundError is raised when Python cannot find a module (a file that ends in .py) with the name given in an import statement.


GREEN: make it pass


  • I use touch to make module_00.py in the src folder

    touch src/module_00.py
    
  • I run the test again

    python3 -m unittest
    
  • I use New-Item to make module_00.py in the src folder

    New-Item src/module_00.py
    
  • I run the test again

    python -m unittest
    
  • the test passes because when import src.module_00 runs, Python brings in an object for the module_00.py file from the src folder so I can use it in tests/test_module_not_found_error.py

    src.module_00
    └── src
        └── module_00.py
    
  • the terminal shows NO TESTS RAN which is confusing since the only way I know the test passed, is because I saw it fail.


REFACTOR: make it better


  • I add an import statement for src.module_01 to tests/test_module_not_found_error.py

    1import src.module_00
    2import src.module_01
    3
    4
    5# Exceptions seen
    6# AssertionError
    7# ModuleNotFoundError
    
  • I run the test again

    python3 -m unittest
    
    python -m unittest
    

    the terminal is my friend, and shows ModuleNotFoundError

    ModuleNotFoundError: No module named 'src.module_01'
    
  • I make a new file named module_01.py in the src folder

    touch src/module_01.py
    
    New-Item src/module_01.py
    

    the terminal goes back to the command line.

  • I run the test

    python3 -m unittest
    
    python -m unittest
    

    the test passes because import src.module_01 brings in an object for the module_01.py file from the src folder so I can use it in tests/test_module_not_found_error.py.

    src.module_01
    └── src
        └── module_01.py
    
  • I add an import statement for src.module_02 to tests/test_module_not_found_error.py

    1import src.module_00
    2import src.module_01
    3import src.module_02
    4
    5
    6# Exceptions seen
    7# AssertionError
    8# ModuleNotFoundError
    
  • I go to the terminal to run the test

    python3 -m unittest
    
    python -m unittest
    

    the terminal is my friend, and shows ModuleNotFoundError

    ModuleNotFoundError: No module named 'src.module_02'
    
  • I make a new file named module_02.py in the src folder

    touch src/module_02.py
    
    New-Item src/module_02.py
    

    the terminal goes back to the command line.

  • I run the test again

    python3 -m unittest
    
    python -m unittest
    

    the test passes because import src.module_02 brings in an object for the module_02.py file from the src folder so I can use it in tests/test_module_not_found_error.py.

    src.module_02
    └── src
        └── module_02.py
    
  • I add an import statement for src.module_03 to tests/test_module_not_found_error.py

    1import src.module_00
    2import src.module_01
    3import src.module_02
    4import src.module_03
    5
    6
    7# Exceptions seen
    
  • I go to the terminal to run the test

    python3 -m unittest
    
    python -m unittest
    

    the terminal is my friend, and shows ModuleNotFoundError

    ModuleNotFoundError: No module named 'src.module_03'
    
  • I make a new file named module_03.py in the src folder

    touch src/module_03.py
    
    New-Item src/module_03.py
    

    the terminal goes back to the command line.

  • I run the test again

    python3 -m unittest
    
    python -m unittest
    

    the test passes because import src.module_03 brings in an object for the module_03.py file from the src folder so I can use it in tests/test_module_not_found_error.py.

    src.module_03
    └── src
        └── module_03.py
    
  • I add an import statement for src.module_04 to tests/test_module_not_found_error.py

    1import src.module_00
    2import src.module_01
    3import src.module_02
    4import src.module_03
    5import src.module_04
    6
    7
    8# Exceptions seen
    
  • I go to the terminal to run the test

    python3 -m unittest
    
    python -m unittest
    

    the terminal is my friend, and shows ModuleNotFoundError

    ModuleNotFoundError: No module named 'src.module_04'
    
  • I make a new file named module_04.py in the src folder

    touch src/module_04.py
    
    New-Item src/module_04.py
    

    the terminal goes back to the command line.

  • I run the test again

    python3 -m unittest
    
    python -m unittest
    

    the test passes because import src.module_04 brings in an object for the module_04.py file from the src folder so I can use it in tests/test_module_not_found_error.py.

    src.module_04
    └── src
        └── module_04.py
    
  • I add an import statement for src.module_05 to tests/test_module_not_found_error.py

    1import src.module_00
    2import src.module_01
    3import src.module_02
    4import src.module_03
    5import src.module_04
    6import src.module_05
    7
    8
    9# Exceptions seen
    
  • I go to the terminal to run the test

    python3 -m unittest
    
    python -m unittest
    

    the terminal is my friend, and shows ModuleNotFoundError

    ModuleNotFoundError: No module named 'src.module_05'
    
  • I make a new file named module_05.py in the src folder

    touch src/module_05.py
    
    New-Item src/module_05.py
    

    the terminal goes back to the command line.

  • I run the test again

    python3 -m unittest
    
    python -m unittest
    

    the test passes because import src.module_05 brings in an object for the module_05.py file from the src folder so I can use it in tests/test_module_not_found_error.py.

    src.module_05
    └── src
        └── module_05.py
    
  • I add an import statement for src.module_not_found_error to tests/test_module_not_found_error.py

     1import src.module_00
     2import src.module_01
     3import src.module_02
     4import src.module_03
     5import src.module_04
     6import src.module_05
     7import src.module_not_found_error
     8
     9
    10# Exceptions seen
    
  • I go to the terminal to run the test

    python3 -m unittest
    
    python -m unittest
    

    the terminal shows

    NO TESTS RAN
    

    the test passes because import src.module_not_found_error brings in an object (everything is an object) for the module_not_found_error folder that is in the src folder so I can use it in tests/test_module_not_found_error.py.

    src.module_not_found_error
    └── src
        └── module_not_found_error
            └── __init__.py
    
  • I add an import statement for src.doe to tests/test_module_not_found_error.py

     1import src.module_00
     2import src.module_01
     3import src.module_02
     4import src.module_03
     5import src.module_04
     6import src.module_05
     7import src.module_not_found_error
     8import src.doe
     9
    10
    11# Exceptions seen
    
  • I go to the terminal to run the test

    python3 -m unittest
    
    python -m unittest
    

    the terminal is my friend, and shows ModuleNotFoundError

    ModuleNotFoundError: No module named 'src.doe'
    
  • I make a new folder named doe in the src folder

    mkdir src/doe
    

    the terminal goes back to the command line.

  • I run the test again

    python3 -m unittest
    
    python -m unittest
    
    • the test passes because import src.doe brings in an object for the doe folder that is in the src folder so I can use it in tests/test_module_not_found_error.py

      src.doe
      └── src
          └── doe
      
    • this worked even though I did not add an __init__.py file to the folder.

  • I add an import statement for src.doe.john to tests/test_module_not_found_error.py

     1import src.module_00
     2import src.module_01
     3import src.module_02
     4import src.module_03
     5import src.module_04
     6import src.module_05
     7import src.module_not_found_error
     8import src.doe
     9import src.doe.john
    10
    11
    12# Exceptions seen
    
  • I go to the terminal to run the test

    python3 -m unittest
    
    python -m unittest
    

    the terminal is my friend, and shows ModuleNotFoundError

    ModuleNotFoundError: No module named 'src.doe.john'
    
  • I make a new file named john.py in the doe folder in the src folder

    touch src/doe/john.py
    
    New-Item src/doe/john.py
    

    the terminal goes back to the command line.

  • I run the test again

    python3 -m unittest
    
    python -m unittest
    

    the test passes because import src.doe.john brings in an object for the john.py file from the doe folder that is in the src folder so I can use it in tests/test_module_not_found_error.py.

    src.doe.john
    └── src
        └── doe
            └── john.py
    
  • I add an import statement for src.doe.jane to tests/test_module_not_found_error.py

     1import src.module_00
     2import src.module_01
     3import src.module_02
     4import src.module_03
     5import src.module_04
     6import src.module_05
     7import src.module_not_found_error
     8import src.doe
     9import src.doe.john
    10import src.doe.jane
    11
    12
    13# Exceptions seen
    
  • I go to the terminal to run the test

    python3 -m unittest
    
    python -m unittest
    

    the terminal is my friend, and shows ModuleNotFoundError

    ModuleNotFoundError: No module named 'src.doe.jane'
    
  • I make a new file named jane.py in the doe folder in the src folder

    touch src/doe/jane.py
    
    New-Item src/doe/jane.py
    

    the terminal goes back to the command line.

  • I run the test again

    python3 -m unittest
    
    python -m unittest
    

    the test passes because import src.doe.jane brings in an object for the jane.py file from the doe folder that is in the src folder so I can use it in tests/test_module_not_found_error.py.

    src.doe.jane
    └── src
        └── doe
            └── jane.py
    
  • I add an import statement for magic to tests/test_module_not_found_error.py

     1import src.module_00
     2import src.module_01
     3import src.module_02
     4import src.module_03
     5import src.module_04
     6import src.module_05
     7import src.module_not_found_error
     8import src.doe
     9import src.doe.john
    10import src.doe.jane
    11import magic
    12
    13
    14# Exceptions seen
    15# AssertionError
    16# ModuleNotFoundError
    
  • I go to the terminal to run the test

    python3 -m unittest
    
    python -m unittest
    

    the terminal is my friend, and shows ModuleNotFoundError

    ModuleNotFoundError: No module named 'magic'
    
  • I make a new file named magic.py in the main folder of the project (module_not_found_error)

    touch magic.py
    
    New-Item magic.py
    

    the terminal goes back to the command line.

  • I run the test again

    python3 -m unittest
    
    python -m unittest
    

    the test passes because import magic brings in an object (everything is an object) for the magic.py that is in the module_not_found_error folder so I can use it in tests/test_module_not_found_error.py.

    magic
    └── magic.py
    
  • I add the new files and folder to git for tracking

    git add .
    
  • I add a git commit message in the terminal

    git commit --all --message \
    'test ModuleNotFoundError'
    

    the terminal shows a summary of the changes then goes back to the command line.

ModuleNotFoundError is raised when Python cannot find a module (a file that ends in .py) with the name given in an import statement.


close the project

  • I close tests/test_module_not_found_error.py

  • I go back to the terminal

  • I change directory to the parent of module_not_found_error

    cd ..
    

    the terminal is my friend, and shows

    .../pumping_python
    

    I am back in the pumping_python directory.


review


how to view all the commands I typed to test ModuleNotFoundError


I type history in the terminal to see all the commands I typed for this project

history

the terminal shows

cd module_not_found_error
uv init module_not_found_error
cd module_not_found_error
mkdir tests
touch tests/module_not_found_error.py
python3 -m unittest
mv tests/module_not_found_error.py tests/test_module_not_found_error.py
python3 -m unittest
touch tests/__init__.py
python3 -m unittest
python3 -m unittest
git add .
git commit --all --message 'setup project'
python3 -m unittest
touch src/module_00.py
python3 -m unittest
python3 -m unittest
touch src/module_01.py
python3 -m unittest
python3 -m unittest
touch src/module_02.py
python3 -m unittest
python3 -m unittest
touch src/module_03.py
python3 -m unittest
python3 -m unittest
touch src/module_04.py
python3 -m unittest
python3 -m unittest
touch src/module_05.py
python3 -m unittest
python3 -m unittest
python3 -m unittest
mkdir src/doe
python3 -m unittest
python3 -m unittest
touch src/doe/john.py
python3 -m unittest
python3 -m unittest
touch src/doe/jane.py
python3 -m unittest
python3 -m unittest
touch magic.py
python3 -m unittest
python3 -m unittest
git add .
git commit --all --message 'test ModuleNotFoundError'
cd ..

The history program shows all the commands I typed in the terminal

  • I ran python3 -m unittest to see the test fail

  • I ran python3 -m unittest every time I made a change until the test passed

  • I will run python3 -m unittest again when I add any code, to make sure tests that passed before do not fail and that the new code I add does what I want

This means I have to run python3 -m unittest for each part of the Test Driven Development Cycle or any time there is a code change.

I do not want to type python3 -m unittest ever again, I want the computer to do it for me.

The history program shows all the commands I typed in the terminal

  • I ran python -m unittest to see the test fail

  • I ran python -m unittest every time I made a change until the test passed

  • I will run python -m unittest again when I add any code, to make sure tests that passed before do not fail and that the new code I add does what I want

This means I have to run python -m unittest for each part of the Test Driven Development Cycle or any time there is a code change.

I do not want to type python -m unittest ever again, I want the computer to do it for me.


code from the chapter

Do you want to see all the CODE I typed in this chapter?


what is next?

Would you like to see how to run tests automatically?


rate pumping python

If this has been a 7 star experience for you, please CLICK HERE to leave a 5 star review of pumping python. It helps other people get into the book too.