Multiple tests with parametrize
Although we have written tests for all functions, they are not exhaustive. More value combinations need testing.
We can write a test with these coordinates.
def test_above_1():
with patch.object(DistanceISS, 'coordinates_iss', return_value=(1, 1)):
distance_iss = DistanceISS(1.001, 1.001)
assert distance_iss.above() == True
And another test with different coordinates.
def test_above_2():
with patch.object(DistanceISS, 'coordinates_iss', return_value=(1, 1)):
distance_iss = DistanceISS(0.999, 0.999)
assert distance_iss.above() == True
Notice the duplicate code; only one line changes, but four are repeated.
pytest
offers parametrize
to test different combinations without repeating code. This introduces the concept of test vectors, which have two parts:
- π Input: The function arguments, in our case, our position and the ISS coordinates.
- π Expected Output: The expected result, the expected distance between our position and the ISS.
Test vectors continuously verify that given inputs yield expected outputs. In parametrize
, our test vector includes many combinations.
@pytest.mark.parametrize("lat, lon, iss_lat, iss_lon, above", [
(40.4, -3.7, 40.4, -3.702, True),
(34.0, -118.2, 34.001, -118.2, True),
(51.5, -0.1, 0.4, -3.3, False)
])
def test_distance_iss(lat, lon, iss_lat, iss_lon, above):
with patch.object(DistanceISS, 'coordinates_iss', return_value=(iss_lat, iss_lon)):
distance_iss = DistanceISS(lat, lon)
assert distance_iss.above() == above
Running it generates multiple tests, one for each input.
iss_test.py::test_distance_iss[40.4--3.7-40.4--3.702-True]
iss_test.py::test_distance_iss[34.0--118.2-34.001--118.2-True]
iss_test.py::test_distance_iss[51.5--0.1-0.4--3.3-False]