Rocket has gathered his fleet math functions into a module called fleet_math.py. Raven suggests keeping the tests in a separate file, so the module stays tidy.
"The test file imports the module, like the trip planner did," Rocket says. "Then it checks every function."
Raven writes the test cases first, on paper, including an empty list of tanks. "What do you notice about that one?" she asks. "It is the case that broke the fuel report on Monday."
Nova hums. "Interesting," she says. "A test written for a bug you already met will catch it if it ever sneaks back in."
Rocket runs the tests, and one fails. He smiles. "Good. Now I know exactly what to fix."
Here is the first version of the module. It has the same bug as Monday's fuel report:
# fleet_math.py
def average(numbers):
"""Average of a list of numbers."""
return sum(numbers) / len(numbers)
def percent(part, whole):
"""part as a percentage of whole, rounded to 1 decimal place."""
return round(part / whole * 100, 1) The test file sits in the same folder and imports it:
# test_fleet_math.py
import fleet_math
def test_average():
assert fleet_math.average([80, 60, 70]) == 70
assert fleet_math.average([5]) == 5
assert fleet_math.average([]) == 0
def test_percent():
assert fleet_math.percent(1, 4) == 25.0
assert fleet_math.percent(1, 3) == 33.3
test_average()
test_percent()
print("All tests passed") Running test_fleet_math.py shows that the empty list test fails, inside fleet_math.py:
Traceback (most recent call last):
File "test_fleet_math.py", line 13, in <module>
test_average()
File "test_fleet_math.py", line 7, in test_average
assert fleet_math.average([]) == 0
File "fleet_math.py", line 4, in average
return sum(numbers) / len(numbers)
ZeroDivisionError: division by zero # fleet_math.py
def average(numbers):
"""Average of a list of numbers. An empty list gives 0."""
if len(numbers) == 0:
return 0
return sum(numbers) / len(numbers)
def percent(part, whole):
"""part as a percentage of whole, rounded to 1 decimal place."""
return round(part / whole * 100, 1) Run test_fleet_math.py again, and every test passes:
All tests passed
| Statement | True or false? |
|---|---|
| A test file usually imports the module it tests. | ? |
| A test written for an old bug can catch it if it comes back. | ? |
| Once tests pass, you can delete them. | ? |
| The module and the test file must be in the same folder for import to work. | ? |
You found a bug with a test, fixed it, and proved the fix. That is how professional teams work. Next week you build Mission Log, and you will test it the same way.