Installing/Running pytest¶
pytest is a framework for testing Python programs. This page explains how to install and run pytest, and how to write test modules.
Installing pytest¶
Complete the following steps in Thonny:
- Type the following command in the shell:
!pip install pytest-cov
- Go to Tools > Options…
- Make sure you have
FORCE_COLOR=1
under environment variables (see instructions). - If needed, close and restart Thonny for the changes to take effect.
- Make sure you have
Example code¶
As a reminder, you should create a new folder for each assignment. Tools like ruff and pytest analyze every file under the current folder. If you don't organize your files into folders, the tools are harder to use.
Create a new folder named geometry
under your CS149
folder.
Download the following files into your geometry
folder.
(Right click each link, and "Save link as…")
Running pytest¶
In Thonny, open triangles.py
and test_triangles.py
(in the geometry
folder you created).
Run the triangles.py
program.
You should see the following output:
valid((3, 4, 5)): True
area((3, 4, 5)): 6.0
classify((3, 4, 5)): Scalene
Note
Running a program puts Thonny's shell in the same folder as the program. You need to be in the correct folder for pytest (and ruff) to find your program.
To run pytest, type the following command in Thonny's shell:
!pytest
This command runs every module in the current folder beginning with the word test_
.
Within each module, every function beginning with the word test_
is called.
If any assertions fail, a detailed error message is displayed.
Exercise 1
The example code currently passes all tests.
To see what failing a test looks like, introduce a bug in triangles.py
.
For example, edit line 46 to say 0.0 * (a + b + c)
instead of 0.5
.
Then run the pytest command again in the shell.
approx()
function¶
Because floating-point arithmetic is imprecise, comparison with ==
can be unreliable.
For example, 0.1 + 0.2 == 0.3
is False
, because 0.1 + 0.2
is 0.30000000000000004
.
Pytest includes a function named approx()
that checks if the expected value is within a small difference of the other value.
So, 0.1 + 0.2 == approx(0.3)
is True
.
Notice that test_area()
uses approx()
, because the area()
function returns a float
.
Exercise 2
Run the following lines, one at a time, in the shell:
0.1 + 0.2
0.1 + 0.2 == 0.3
from pytest import approx
approx(0.3)
0.1 + 0.2 == approx(0.3)
Keyboard shortcuts¶
In Thonny, use the keyboard shortcut Alt+S to switch to the shell. And use the keyboard shortcut Alt+E to switch back to the editor. Then you won't have to reach for the mouse every time you want to run pytest.
Also, press the Up and Down buttons in the shell to recall previous commands. Then you won't have to retype the same command over and over while testing.
Note for Mac users (click to expand)
The keyboard shortcuts are different on macOS. Press Cmd+Option+S for the shell and Cmd+Option+E for the editor.
These shortcuts might not work in the current version of macOS. However, you can define your own shortcuts by following these steps:
- From the Thonny "Tools" menu, select "Open Thonny data folder…"
- Close Thonny (otherwise your changes will be overwritten when Thonny is closed).
- Open (double click) the
configuration.ini
file in the data folder. - Add the following lines to the end of the file:
[shortcuts] focus_shell = <Control-s> focus_editor = <Control-e>
- Save
configuration.ini
, and reopen Thonny. - Use Ctrl+S for the shell and Ctrl+E for the editor.
For more information, see Custom shortcuts on Thonny's Wiki.
Exercise 3
Practice using each of the keyboard shortcuts described above.
Optional arguments¶
pytest works the same way as ruff. If you run pytest without any arguments, all test modules will be run. Alternatively, you can run a specific test module as follows:
!pytest test_triangles.py
In addition, you can run a specific test function using the -k
option.
!pytest -k test_area
Finally, the -q
(quiet) option can be used to make the output less verbose.
!pytest -q
Multiple options can be combined.
!pytest -q -k test_area
Exercise 4
Run each command listed above and see how the output changes.
And if you haven't already, fix the bug you added on line 46
of triangles.py
(change the 0.0
back to 0.5
).
Unit Testing¶
Test functions use Python's assert
statement.
- Ex:
assert a % 2 == 0, "value was odd, should be even"
- The error message after the comma is optional, but helpful.
Follow this pattern when testing your own programs:
- For every module
m
, create a module namedtest_m
. - For every function
f
, write a function namedtest_f
. - Write enough
assert
statements to test every branch.
Exercise 5
The provided test functions are incomplete.
There are many possible errors that these tests wouldn't catch.
Add more assert
statements to each function in test_trianges.py
.
Each assert
should have different triangle values and expected results.
Try to test every possible branch (return value) of each function.
Submit your test_trianges.py
to Gradescope.
Going further¶
See pytest's documentation and API Reference for additional details.