Chapter 2 · Practice 3 of 5
Use table driven tests for many inputs to the same logic
Why it matters
When the same behaviour needs checking with many inputs, copy pasting a test ten times hides the one line that differs. Every major runner supports parametrized tests: test.each in Vitest and Jest, @pytest.mark.parametrize in pytest, subtests with a table in Go.
Each row becomes its own test in the report, so a failure tells you exactly which input broke. Adding a new edge case is one new line.
Keep the table readable: put the input and expected output side by side, and give rows an id when the values alone do not explain the case.
Example
import pytest
from shipping import shipping_cost
@pytest.mark.parametrize(
"weight_kg, expected",
[
(0.5, 200), # small parcel
(1.0, 200), # boundary: still small
(1.01, 350), # just over the boundary
(20.0, 900), # largest allowed
],
)
def test_shipping_cost_by_weight(weight_kg, expected):
assert shipping_cost(weight_kg) == expected
def test_rejects_weight_over_limit():
with pytest.raises(ValueError):
shipping_cost(20.5)