Pytest
A hard truth in this world is that all of humanity is kind dumb. Even you— the coder — are dumb. We will cover how to harden your package against your dumb users, and then how to protect your package from your dumb self.
Protecting Yourself from the User
Let's focus on how we can make the duration
method more stable. First thing first, let's add type hints:
def duration(self, distance: int, speed: int) -> int:
return (distance/speed)*60
Next, we can add raise exceptions for user inputs that may not make sense. For example, if we wanted to prevent the user from inputting a speed over 100 mph we would do the following:
def duration(self, distance: int, speed: int) -> int:
if speed > 100:
raise Exception("Slow down!")
return (distance/speed)*60
Protecting Yourself from Yourself
Now that we have protected our immaculate function from the users, we need to protect it from ourselves. Basically, we are going to see if the method works as we expect.
Make sure you are in your poetry shell
, and then we are going to first install pytest
:
pip install pytest
If you recall, poetry automatically created a tests
folder. In that folder, we are going to put our tests. In order for pytest
to test the tests, each file needed to be prepended with test_
. So let's add tests for our RoadTrip
class.
This will be the directory structure:
roadtrip
├── pyproject.toml
├── README.md
├── roadtrip
│ └── __init__.py
│ └── trip.py
└── tests
└── __init__.py
└── test_roadtrip.py
One thing we would want to do is make sure that the output of duration is what we expect it to be. If we are going 60 mph and going 60 miles, then it should take 60 minutes to get there.
Let's write our duration function to do that and put it into test_roadtrip.py
:
import roadtrip
def test_duration():
trip1 = roadtrip.RoadTrip()
assert 60.0 == trip1.duration(60, 60)
Now in the root folder of our poetry project run pytest
like so:
pytest
It will run the test and should return something like the below if they pass:
========================== test session starts =============================
platform darwin -- Python 3.9.7, pytest-8.0.0, pluggy-1.4.0
rootdir: /Users/corydonbaylor/Documents/github/python_package/roadtrip
collected 1 item
tests/test_roadtrip.py . [100%]
========================== 1 passed in 0.02s ================================
Now let us write a test to make sure that our exception works:
def test_exception():
# creating a instance of roadtrip
trip1 = roadtrip.RoadTrip()
# this will capture the execption as exc
with pytest.raises(Exception) as exc:
trip1.duration(60, 160)
# this will make sure that exc is equal to what it should be
assert str(exc.value) == "Slow down!"