4 Coverage

Read the tutorial. Build it yourself is the other way to read this part.

This walk goes through rahuldave/cheesecracker on GitHub. This part starts from the code at step-03. The code before this part

To look at this code on your machine, run these commands. The first one makes a clone, if this folder has none:

[ -d cheesecracker ] || git clone https://github.com/rahuldave/cheesecracker
cd cheesecracker
git fetch --quiet --tags --force origin
git switch --detach step-03

The tests pass, but nothing says which lines of the code they run. Coverage counts them.

just setup

Twenty-one tests pass, and we still do not know which lines of the app they run. Coverage counts the lines of the package api that run during the tests, and lists the lines that no test ran.

4.1 pytest-cov, to measure what the tests run

A line that no test runs can break with no test failing. pytest-cov adds the option --cov to pytest. The option prints a table with each file and the share of its lines that ran. It is a tool of the tests, so it goes into the group test.

This change came from running uv add --group test pytest-cov.

The check runs the unit tests alone, with coverage of the package api.

uv run pytest tests/unit --cov=api -q

The table shows utils.py at 100% and service.py at 0%. The unit tests call power(), and never the app.

What changed

  • pyproject.toml: pytest-cov, in the group test. 1 line added. It comes from uv add --group test pytest-cov. The file
    • look at "pytest-cov>=7.1.0",
  • uv.lock: the exact versions of pytest-cov, and of coverage, which it uses. 115 lines added. It comes from uv add --group test pytest-cov. The file

The diff of pyproject.toml
@@ -20,6 +20,7 @@ test = [
     "httpx2>=2.13.1",
     "pytest>=9.1.1",
     "pytest-asyncio>=1.4.0",
+    "pytest-cov>=7.1.0",
 ]
 
 [tool.pytest.ini_options]

This change on GitHub The code after it

4.2 just cov shows which lines the tests run

The recipe cov runs every test with coverage, and adds the column Missing, with the numbers of the lines that no test ran.

± See the change to justfile

The recipe cov, at the end of the justfile, runs pytest with --cov=api --cov-report=term-missing, and passes on to pytest any words that you type after just cov.

just cov -q

The total is 95%. service.py misses line 31, the answer of /health, because no test asks for it.

What changed

  • justfile: the recipe cov. 4 lines added. The file
    • look at uv run pytest --cov=api --cov-report=term-missing "$@"

The diff of justfile
@@ -40,3 +40,7 @@ stop:
     done
     echo "stop: the server still answers after 30 seconds" >&2
     exit 1
+
+# Run the tests, and show which lines of the package api they ran. Extra arguments go to pytest: just cov tests/unit
+cov *args:
+    uv run pytest --cov=api --cov-report=term-missing "$@"

This change on GitHub

This part ends at the code at step-04. The code after this part