how to run tests automatically
In the previous chapters
I ran
python3 -m unittestto see the test failI ran
python3 -m unittestevery time I made a change until the test passed
I run python3 -m unittest for each part of the Test Driven Development Cycle or any time there is a code change. I want the computer to automatically run the tests for me.
preview
This is one way to automatically run tests in a Python Test Driven Development project. By the end of the chapter you will know these commands better
cd
echo
tree
cat
uv run pytest-watcher
source .venv/bin/activate
deactivate
history
questions about how to run tests automatically
Questions to think about as I go through the chapter
open the project
I change directory to the
personfoldercd personthe terminal shows I am in the
personfolder.../pumping_python/personI use tree to see what the project looks like, as a reminder
tree -a -L 2the terminal shows
. ├── .git │ ├── config │ ├── description │ ├── FETCH_HEAD │ ├── HEAD │ ├── hooks │ ├── info │ ├── objects │ └── refs ├── .gitignore ├── pyproject.toml ├── .python-version ├── README.md ├── src │ └── person.py └── tests ├── __init__.py ├── __pycache__ └── test_person.pyI can use pytest-watcher to run tests automatically. It is a Python program that automatically runs pytest any time a Python file changes in the folder it is looking at, this means it will run the tests for me every time I make a change.
pytest is a Python package like unittest that is used for testing. It is not part of The Python Standard Library.
I use uv to run pytest-watcher in the terminal
uv run pytest-watcherthe terminal is my friend, and shows
Using CPython 3.X.Y Creating virtual environment at: .venv error: Failed to spawn: `pytest-watcher` Caused by: No such file or directory (os error 2)because pytest-watcher is not installed on the computer. I can install pytest-watcher with the uv Python Package Manager
the message also shows
Creating virtual environment at: .venv
I use tree to see what the project looks like now
tree -a -L 2the terminal shows
. ├── .git │ ├── config │ ├── description │ ├── FETCH_HEAD │ ├── HEAD │ ├── hooks │ ├── info │ ├── objects │ └── refs ├── .gitignore ├── pyproject.toml ├── .python-version ├── README.md ├── src │ └── person.py ├── tests │ ├── __init__.py │ ├── __pycache__ │ └── test_person.py └── .venv ├── bin ├── CACHEDIR.TAG ├── .gitignore ├── lib ├── lib64 -> lib ├── .lock └── pyvenv.cfguv made a virtual environment in a folder named
.venvwith files and folders.
what is a virtual environment?
A virtual environment is a separate folder where I can install Python packages that my project needs. This helps me keep things that belong to the project in one place, separate from other things on the computer.
It means I can have a separate virtual environment for every project with only the programs that the project needs. I do not have to keep every program I have ever used for projects that do not need them.
how to write text to a file
I want to make a file where I list all the Python packages that my project needs as a way to document it and have uv install the programs listed in the file
I can write text to a file with the echo program, it shows whatever it is given as an argument, on the screen. For example, if I type this in the terminal
echo "hi, my name is Jacob"it shows
hi, my name is JacobI can also use echo to add text to a file. I use it to make the requirements file with pytest as what is inside it
echo "pytest" > requirements.txt>is an operator that is used to send output from a program to the given filepytest is a Python package like unittest, that is used for testing
requirements.txtis the name of the file where I add names of Python packages for the uv Python Package Manager to install. The namerequirements.txtis Python convention, I can use any name I want for the requirements file.
I use tree to see what the project looks like now
tree -a -L 1the terminal shows
. ├── .git ├── .gitignore ├── pyproject.toml ├── .python-version ├── README.md ├── requirements.txt ├── src ├── tests └── .venvrequirements.txtis now in thepersonfolderI use the cat program to look at what is in
requirements.txtcat requirements.txtthe terminal shows
pytestI add pytest-watcher to the requirements file as well
echo "pytest-watcher" >> requirements.txt>>is an operator that is used to send output from a program to the given file, it adds to what is in the file without writing over itpytest-watcher is a Python program that automatically runs pytest when I change code in the project
I use cat to look at what is in
requirements.txtnowcat requirements.txtthe terminal shows
pytest pytest-watcherlife is good!
how to install Python packages with uv
I use uv to install pytest-watcher from the requirements file
uv add --requirement requirements.txt--requirementis an option that can be given to theaddargument for Python packages in a given filerequirements.txtis the name of the given file. It helps to manage Python programs that are needed by the project. In this case I only have two programs. A project can have a big number of programs it needs and using one file with one command is easier than one command for each program
the terminal is my friend, and shows setup and installation
Resolved 9 packages in GHIms ░░░░░░░░░░░░░░░░░░░░ [0/7] Installing wheels... ... Installed 7 packages in JKLms + iniconfig==A.B.C + packaging==DE.F + pluggy==G.H.I + pygments==J.K.L + pytest==M.N.O + pytest-watcher==P.Q.R + watchdog==S.T.UI run tree to see what changed in the project
tree -a -L 1the terminal shows
. ├── .git ├── .gitignore ├── pyproject.toml ├── .python-version ├── README.md ├── requirements.txt ├── src ├── tests ├── uv.lock └── .venvuv added
uv.locka file that has the exact versions of the Python programs that were installed.I use cat to show what is now in
pyproject.tomlcat pyproject.tomlthe terminal is my friend, and shows
[project] name = "person" version = "0.1.0" description = "Add your description here" readme = "README.md" requires-python = ">=3.XY" dependencies = [ "pytest>=M.N.O", "pytest-watcher>=P.Q.R", ]it added pytest and pytest-watcher to the dependencies of the project.
how to activate a virtual environment
When I want to work in a virtual environment, I make sure I am in the parent folder of the virtual environment. In this case person is the parent. I activate the virtual environment in the terminal to use it
source .venv/bin/activate
the terminal is my friend, and shows
(person) .../pumping_python/person
(person) on the far left of the command line in the terminal shows that I am working in the virtual environment.
how to deactivate a virtual environment
I can leave the virtual environment by typing deactivate in the terminal
deactivate
the terminal goes back to the command line
.../pumping_python/person
(person) is no longer on the left side.
how to run tests automatically with uv and pytest-watcher
I open
test_person.pyfrom thetestsfolderI change
assert False is Falsetoassert False is Trueintest_person.py# False is True assert False is True # assert False is False # Exceptions seen # AssertionErrorI go back to the terminal to run the test again
uv run pytest-watcher . --nowthe terminal is my friend, and shows an error without going back to the command line
pytest-watcher version X.Y.Z Runner command: pytest Waiting for file changes in .../pumping_python/person =================== test session starts ==================== platform ____ -- Python 3.A.B, pytest-C.D.E, pluggy-F.G.H rootdir: .../pumping_python/person configfile: pyproject.toml collected 0 items / 1 error ========================== ERRORS ========================== ___________ ERROR collecting tests/test_person.py ___________ tests/test_person.py:2: in <module> assert False is True E assert False is True ================= short test summary info ================== ERROR tests/test_person.py - assert False is True !!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!! ===================== 1 error in I.JKs ===================== [pytest-watcher] Current runner args: [] Press w to show menu
how to open the test file in the editor from the terminal
I hold ctrl (Windows/Linux) or option/command (MacOS) on the keyboard, then click on
tests/test_person.pyto go back totest_person.py. I change True to False on line 21# False is True 2# assert False is True 3assert False is False 4 5 6# Exceptions seen 7# AssertionErrorthe terminal is my friend, and shows AssertionError
[ptw] Detected modified: ./tests/test_person.py -> =================== test session starts ==================== platform ____ -- Python 3.A.B, pytest-C.D.E, pluggy-F.G.H rootdir: .../pumping_python/person configfile: pyproject.toml collecting ... [ptw] Detected modified: ./tests/test_person.py -> [ptw] Detected modified: ./tests/test_person.py -> collected 0 items ================== no tests ran in 0.01s =================== [pytest-watcher] Current runner args: [] Press w to show menupytest-watcher “saw” the change I made to
test_person.pyand ran the test againthe terminal shows
no tests ranwhich is confusing since the only way I know the test passed, is because I saw it fail
I can write the rest of the code for the project and get results back quickly because the tests run when I change the code.
I want to write code that represents a person, after I learn what an assertion is.
how to stop the automated tests
I go to the terminal and use q on the keyboard to stop the tests, the terminal goes back to the command line.
.../pumping_python/person
close the project
I click in the terminal then 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 \ 'automate tests'the terminal shows a summary of the changes then goes back to the command line.
I close
test_person.pyI change directory to the parent of
personcd ....is for the parent of any directory I am in. the terminal shows.../pumping_pythonI am back in the
pumping_pythonfolder.
review
I gave the computer some commands to automate running tests for my Python Test Driven Development environment
I used uv to make a virtual environment
how to view all the commands I typed to automate running tests
I type history in the terminal to see all the commands I have typed so far
historythe terminal shows
cd person uv run pytest-watcher echo "hi, my name is Jacob" echo "pytest" > requirements.txt tree -a -L 1 cat requirements.txt echo "pytest-watcher" >> requirements.txt cat requirements.txt uv add --requirement requirements.txt tree -a -L 1 cat pyproject.toml source .venv/bin/activate deactivate uv run pytest-watcher . --now code tests/test_person.py uv run pytest-watcher . --now git status git add . git commit --all --message 'automate tests' cd ..the history program shows all the commands I typed in the terminal so far
these are the commands I used to make a Python Test Driven Development environment
uv init NAME_OF_THE_PROJECT cd NAME_OF_THE_PROJECT mkdir src mv main.py src/NAME_OF_THE_PROJECT.py mkdir tests touch tests/__init__.py touch tests/test_NAME_OF_THE_PROJECT.py echo "pytest" > requirements.txt echo "pytest-watcher" >> requirements.txt uv add --requirement requirements.txt uv run pytest-watcher . --nowwhere
NAME_OF_THE_PROJECTis the name I give the projectthese are the steps I took to make a Python Test Driven Development environment
give the project a name
make a Python file to hold the source code in the ‘src’ folder
make the test pass
How many questions can you answer after going through this chapter?
what is next?
You know
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.