Testing a class through its behaviour
A test that reads private attributes, such as cart._items, is tied to one way of writing the class. Refactor the inside and the test breaks, though nothing a caller can see has changed. Tests that go through the public methods fail only when behaviour changes, which is the only time you want them to.
class Tally:
def __init__(self):
self._counts = {}
def add(self, word):
n = self._counts.get(word, 0)
self._counts[word] = n + 1
def count(self, word):
return self._counts.get(word, 0)
def test_add_counts_repeats():
tally = Tally()
tally.add("a")
tally.add("a")
assert tally.count("a") == 2
test_add_counts_repeats()
print("passed without reading _counts")What to cover
List what a caller relies on and give each its own test: what a new object reports, what each method changes, what happens at a limit, and what is refused. If a behaviour can only be seen through a private attribute, ask whether any caller needs it.
Your task
LRUCache is written for you. Using only get, put and len, write test_get_returns_value_or_default (a stored value, and a default you pass for a missing key), test_evicts_least_recently_used (capacity 2: put a and b, get a, put c), test_update_does_not_grow and test_rejects_zero_capacity.
The explanation opens here once every check passes.