Skip to content

← Testing with pytest and Hypothesis step 2 of 19

Easy Primitives

Catch the Broken Versions

Your web API returns results 10 to a page, and tells the client how many pages there are. page_count(items, per_page) works that out. It rounds up, because a last page with only a few results is still a page:

page_count(25, 10)  # 3
page_count(20, 10)  # 2
page_count(0, 10)   # 0

The starter has five versions of page_count. Two are correct. Three have a bug that is easy to write by accident. Write the check that tells them apart.

What to write

Fill in check(fn). It calls fn on example inputs that you choose, and compares each result with the answer you expect.

  • Return True if every result is right, and False if any result is wrong.
  • check must return True for both correct versions, and False for each of the three broken ones.
  • Use a per_page of at least 1 in every case. items can be 0.

The five versions

Name What it returns
correct (items + per_page - 1) // per_page
correct, rewritten the same answers, worked out with divmod
rounds down items // per_page
adds a page items // per_page + 1
never zero the correct answer, but never less than 1

Read each broken version and ask which input shows its bug. A check that tries only page_count(25, 10) catches one of the three.

What the driver reports

Keep VERSIONS and solve as they are. solve(names=...) runs check on each version you name, and returns a dictionary that maps each name to the result.

Pick cases that fail when the code is wrong

A useful case is one that a plausible bug gets wrong. Here that means a partly full last page, an exactly full one, and no items at all. The rewritten version is there for a second reason. A check that compares results, and never looks at how fn works, still passes after a correct rewrite.

The grader cannot run pytest, so check returns True or False. In a real project, each case would be an assert in a pytest test. Later in this track, parametrize runs one test over a table of cases like yours.