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
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_errorI open a terminal
I change directory to the
module_not_found_errorproject in thepumping_pythonfoldercd module_not_found_errorthe terminal shows
cd: no such file or directory: module_not_found_errorthere is no folder with the name
module_not_found_errorin this folder.I use the uv Python Package Manager to setup the project
uv init module_not_found_errorthe terminal shows
Initialized project `module-not-found-error` at `.../pumping_python/module_not_found_error`I change directory to the
module_not_found_errorfoldercd module_not_found_errorthe terminal shows
.../pumping_python/module_not_found_errorI make a child folder to keep the tests separate from the other files
mkdir teststhe terminal goes back to the command line.
I add an empty file to the
testsfoldertouch tests/module_not_found_error.pyNew-Item tests/module_not_found_error.pyI open
module_not_found_error.pyfrom thetestsfolderI add the first failing test to
module_not_found_error.pyin thetestsfolder1assert False is TrueI use the unittest module to run tests
python3 -m unittestpython -m unittestthe terminal shows
------------------------------------------------------ Ran 0 tests in 0.000s NO TESTS RANI close
module_not_found_error.pyDanger
if you do not close
module_not_found_error.py, there will be 3 files in thetestsfolder after the next step (instead of 2), because theAuto Savefeature (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.pyin thetestsfolder totest_module_not_found_error.pymv tests/module_not_found_error.py \ tests/test_module_not_found_error.pyMove-Item tests/module_not_found_error.py \ tests/test_module_not_found_error.pythe terminal goes back to the command line.
I try to run the test again
python3 -m unittestpython -m unittestthe terminal still shows
NO TESTS RAN.
Danger
use 2 underscores (__) before and after init for __init__.py not _init_.py
I make the
testsdirectory a Python packagetouch tests/__init__.pyI try to run the test again
python3 -m unittest
I make the
testsdirectory a Python packageNew-Item tests/__init__.pyI 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 1in 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.py1assert False is True 2 3 4# Exceptions seen 5# AssertionError-
1# assert False is True 2assert False is False 3 4 5# Exceptions seen 6# AssertionError I run the test again
python3 -m unittestpython -m unittestthe 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# AssertionErrorI run the test again
python3 -m unittestpython -m unittestthe 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_00runs, Python tries to bring in an object (everything in Python is an object) for themodule_00.pyfile from thesrcfolder.I add ModuleNotFoundError to the list of Exceptions seen, in
test_module_not_found_error.py4# 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 go back to the terminal
the test passes because when
import src.module_00runs, Python brings in an object for themodule_00.pyfile from thesrcfolder so I can use it intests/test_module_not_found_error.pysrc.module_00 └── src └── module_00.pythe terminal shows
NO TESTS RANwhich 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_01totests/test_module_not_found_error.py1import src.module_00 2import src.module_01 3 4 5# Exceptions seen 6# AssertionError 7# ModuleNotFoundErrorI run the test again
python3 -m unittestpython -m unittestthe terminal is my friend, and shows ModuleNotFoundError
ModuleNotFoundError: No module named 'src.module_01'I make a new file named
module_01.pyin thesrcfoldertouch src/module_01.pyNew-Item src/module_01.pythe terminal goes back to the command line.
I run the test
python3 -m unittestpython -m unittestthe test passes because
import src.module_01brings in an object for themodule_01.pyfile from thesrcfolder so I can use it intests/test_module_not_found_error.py.src.module_01 └── src └── module_01.pyI add an import statement for
src.module_02totests/test_module_not_found_error.py1import src.module_00 2import src.module_01 3import src.module_02 4 5 6# Exceptions seen 7# AssertionError 8# ModuleNotFoundErrorI go to the terminal to run the test
python3 -m unittestpython -m unittestthe terminal is my friend, and shows ModuleNotFoundError
ModuleNotFoundError: No module named 'src.module_02'I make a new file named
module_02.pyin thesrcfoldertouch src/module_02.pyNew-Item src/module_02.pythe terminal goes back to the command line.
I run the test again
python3 -m unittestpython -m unittestthe test passes because
import src.module_02brings in an object for themodule_02.pyfile from thesrcfolder so I can use it intests/test_module_not_found_error.py.src.module_02 └── src └── module_02.pyI add an import statement for
src.module_03totests/test_module_not_found_error.py1import src.module_00 2import src.module_01 3import src.module_02 4import src.module_03 5 6 7# Exceptions seenI go to the terminal to run the test
python3 -m unittestpython -m unittestthe terminal is my friend, and shows ModuleNotFoundError
ModuleNotFoundError: No module named 'src.module_03'I make a new file named
module_03.pyin thesrcfoldertouch src/module_03.pyNew-Item src/module_03.pythe terminal goes back to the command line.
I run the test again
python3 -m unittestpython -m unittestthe test passes because
import src.module_03brings in an object for themodule_03.pyfile from thesrcfolder so I can use it intests/test_module_not_found_error.py.src.module_03 └── src └── module_03.pyI add an import statement for
src.module_04totests/test_module_not_found_error.py1import src.module_00 2import src.module_01 3import src.module_02 4import src.module_03 5import src.module_04 6 7 8# Exceptions seenI go to the terminal to run the test
python3 -m unittestpython -m unittestthe terminal is my friend, and shows ModuleNotFoundError
ModuleNotFoundError: No module named 'src.module_04'I make a new file named
module_04.pyin thesrcfoldertouch src/module_04.pyNew-Item src/module_04.pythe terminal goes back to the command line.
I run the test again
python3 -m unittestpython -m unittestthe test passes because
import src.module_04brings in an object for themodule_04.pyfile from thesrcfolder so I can use it intests/test_module_not_found_error.py.src.module_04 └── src └── module_04.pyI add an import statement for
src.module_05totests/test_module_not_found_error.py1import 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 seenI go to the terminal to run the test
python3 -m unittestpython -m unittestthe terminal is my friend, and shows ModuleNotFoundError
ModuleNotFoundError: No module named 'src.module_05'I make a new file named
module_05.pyin thesrcfoldertouch src/module_05.pyNew-Item src/module_05.pythe terminal goes back to the command line.
I run the test again
python3 -m unittestpython -m unittestthe test passes because
import src.module_05brings in an object for themodule_05.pyfile from thesrcfolder so I can use it intests/test_module_not_found_error.py.src.module_05 └── src └── module_05.pyI add an import statement for
src.module_not_found_errortotests/test_module_not_found_error.py1import 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 seenI go to the terminal to run the test
python3 -m unittestpython -m unittestthe terminal shows
NO TESTS RANthe test passes because
import src.module_not_found_errorbrings in an object (everything is an object) for themodule_not_found_errorfolder that is in thesrcfolder so I can use it intests/test_module_not_found_error.py.src.module_not_found_error └── src └── module_not_found_error └── __init__.pyI add an import statement for
src.doetotests/test_module_not_found_error.py1import 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 seenI go to the terminal to run the test
python3 -m unittestpython -m unittestthe terminal is my friend, and shows ModuleNotFoundError
ModuleNotFoundError: No module named 'src.doe'I make a new folder named
doein thesrcfoldermkdir src/doethe terminal goes back to the command line.
I run the test again
python3 -m unittestpython -m unittestI add an import statement for
src.doe.johntotests/test_module_not_found_error.py1import 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 seenI go to the terminal to run the test
python3 -m unittestpython -m unittestthe terminal is my friend, and shows ModuleNotFoundError
ModuleNotFoundError: No module named 'src.doe.john'I make a new file named
john.pyin thedoefolder in thesrcfoldertouch src/doe/john.pyNew-Item src/doe/john.pythe terminal goes back to the command line.
I run the test again
python3 -m unittestpython -m unittestthe test passes because
import src.doe.johnbrings in an object for thejohn.pyfile from thedoefolder that is in thesrcfolder so I can use it intests/test_module_not_found_error.py.src.doe.john └── src └── doe └── john.pyI add an import statement for
src.doe.janetotests/test_module_not_found_error.py1import 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 seenI go to the terminal to run the test
python3 -m unittestpython -m unittestthe terminal is my friend, and shows ModuleNotFoundError
ModuleNotFoundError: No module named 'src.doe.jane'I make a new file named
jane.pyin thedoefolder in thesrcfoldertouch src/doe/jane.pyNew-Item src/doe/jane.pythe terminal goes back to the command line.
I run the test again
python3 -m unittestpython -m unittestthe test passes because
import src.doe.janebrings in an object for thejane.pyfile from thedoefolder that is in thesrcfolder so I can use it intests/test_module_not_found_error.py.src.doe.jane └── src └── doe └── jane.pyI add an import statement for
magictotests/test_module_not_found_error.py1import 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# ModuleNotFoundErrorI go to the terminal to run the test
python3 -m unittestpython -m unittestthe terminal is my friend, and shows ModuleNotFoundError
ModuleNotFoundError: No module named 'magic'I make a new file named
magic.pyin the main folder of the project (module_not_found_error)touch magic.pyNew-Item magic.pythe terminal goes back to the command line.
I run the test again
python3 -m unittestpython -m unittestthe test passes because
import magicbrings in an object (everything is an object) for themagic.pythat is in themodule_not_found_errorfolder so I can use it intests/test_module_not_found_error.py.magic └── magic.pyI 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.pyI go back to the terminal
I change directory to the parent of
module_not_found_errorcd ..the terminal is my friend, and shows
.../pumping_pythonI am back in the
pumping_pythondirectory.
review
I ran a test for ModuleNotFoundError to practice making Python modules.
The terminal shows
NO TESTS RANwhen there is no test and when my test passes which is confusing since the only way I know the test passed, is because I saw it fail. There has to be a better way.
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 unittestto see the test failI ran
python3 -m unittestevery time I made a change until the test passedI will run
python3 -m unittestagain 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 unittestto see the test failI ran
python -m unittestevery time I made a change until the test passedI will run
python -m unittestagain 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
what is next?
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.