← Back to course
Code Crew G5 / Week 11 / Thursday
4/6
Week 11 Β· Plan your capstone

Thursday

Tests come first
// Choose, break it down, test it first
⏱ about 15 min

Thursday: Tests come first

Rocket wrote total_items in a rush. It printed a big number, and he cheered. "It works!"

Raven asks, "How do you know it is right? What do you notice about the number?"

Rocket adds the supplies by hand. The program is off by one. "Oh. It is wrong!"

"If you had decided the right answer first, you would have spotted it right away," Raven says.

Nova shines. "Here is a hint. Write down what you expect before you press run."

A tiny test helper

A test case is an input and the output you expect. The check function compares what the code gave with what we wanted.

def check(label, got, want):
    if got == want:
        print("PASS", label)
    else:
        print("FAIL", label, "got", got, "want", want)

def total_items(stock):
    total = 1
    for item in stock:
        total = total + stock[item]
    return total

check("total", total_items({"a": 2, "b": 3}), 5)
check("total of nothing", total_items({}), 0)
Output:
FAIL total got 6 want 5
FAIL total of nothing got 1 want 0

Both tests fail, and they point right at the bug. total starts at 1 instead of 0. A test with an empty dictionary is an edge case. It catches this bug clearly.

Which number should total start at to make both tests pass?
WHY THIS EXERCISEA running total must start at 0, or every answer is off by the starting amount.

Write the expected answers

Here are tests for the tracker. Work out each expected answer by hand, before any code runs.

total_items({"a": 4, "b": 4, "c": 1}) should be:
low_stock({"b": 9, "c": 0, "a": 1}, 5) lists the supplies under 5, A to Z. Type the list.
count_crew on the week 10 command tree should be:
SPOT THE EDGE CASE.
  • Read the question.
  • Tap your answer.
Which test is an edge case for find_item?

Practice lab: a test catches a bug

def check(label, got, want):
    if got == want:
        print("PASS", label)
    else:
        print("FAIL", label, "got", got, "want", want)

def count_low(stock, limit):
    count = 0
    for item in stock:
        if stock[item] <= limit:
            count = count + 1
    return count

check("two low", count_low({"a": 1, "b": 9, "c": 3}, 5), 2)
check("at the limit", count_low({"a": 5}, 5), 0)
check("empty", count_low({}, 5), 0)
How many tests PASS?
How many tests FAIL?
Which test caught the bug? Type its label.
After the fix, what does count_low({"a": 5, "b": 4}, 5) return?
TEST CHECK
  • Read the question.
  • Tap your answer.
How should count_low be fixed?
Why work out the expected answer before running?
Which is an edge case for total_items?
StatementTrue or false?
The test labelled two low passes.?
A passing test proves there are no bugs anywhere.?
A count right at the limit is an edge case.?
check prints the got and want values when a test fails.?
WHY THIS EXERCISEMore good tests, including edge cases, catch more bugs.
After the fix, how many tests pass?
WHY THIS EXERCISEWith < in place, all three expected answers match.

Excellent! Tests turn "I think it works" into "I know it works." Tomorrow we look at how a capstone is judged.

← Wednesday