KKitForma.

Language

EnglishEnglishTürkçeTurkishTool unavailable · open catalogDeutschGermanTool unavailable · open catalogEspañolSpanishTool unavailable · open catalogFrançaisFrenchTool unavailable · open catalogPortuguêsPortugueseTool unavailable · open catalogItalianoItalianTool unavailable · open catalogNederlandsDutchTool unavailable · open catalogPolskiPolishTool unavailable · open catalogРусскийRussianTool unavailable · open catalogУкраїнськаUkrainianTool unavailable · open catalogSvenskaSwedishTool unavailable · open catalogNorskNorwegianTool unavailable · open catalogDanskDanishTool unavailable · open catalogSuomiFinnishTool unavailable · open catalogČeštinaCzechTool unavailable · open catalogRomânăRomanianTool unavailable · open catalogΕλληνικάGreekTool unavailable · open catalogالعربيةArabicTool unavailable · open catalogעבריתHebrewTool unavailable · open catalogفارسیPersianTool unavailable · open catalogاردوUrduTool unavailable · open catalogहिन्दीHindiTool unavailable · open catalogবাংলাBengaliTool unavailable · open catalogதமிழ்TamilTool unavailable · open catalogతెలుగుTeluguTool unavailable · open catalogमराठीMarathiTool unavailable · open catalogગુજરાતીGujaratiTool unavailable · open catalog简体中文Chinese SimplifiedTool unavailable · open catalog繁體中文Chinese TraditionalTool unavailable · open catalog日本語JapaneseTool unavailable · open catalog한국어KoreanTool unavailable · open catalogTiếng ViệtVietnameseTool unavailable · open catalogไทยThaiTool unavailable · open catalogBahasa IndonesiaIndonesianTool unavailable · open catalogBahasa MelayuMalayTool unavailable · open catalogFilipinoFilipinoTool unavailable · open catalogKiswahiliSwahiliTool unavailable · open catalogAfrikaansAfrikaansTool unavailable · open catalogMagyarHungarianTool unavailable · open catalogБългарскиBulgarianTool unavailable · open catalogHrvatskiCroatianTool unavailable · open catalogSrpskiSerbianTool unavailable · open catalogSlovenčinaSlovakTool unavailable · open catalogSlovenščinaSlovenianTool unavailable · open catalogLietuviųLithuanianTool unavailable · open catalogLatviešuLatvianTool unavailable · open catalogEestiEstonianTool unavailable · open catalogCatalàCatalanTool unavailable · open catalogEuskaraBasqueTool unavailable · open catalog
← All learning paths

Free learning • no account required

Debug Python with reproducible tests

Turn a failing example into a small regression suite, control time without sleeping, and test mutable state without leaking between cases.

Explain a failure, fix its cause, and keep tests that detect boundary, clock and state regressions.

Suggested study time: 180 minutes, plus your project. Go at your own pace.

Before you start: prerequisites and scope
  • Complete Python data foundations, especially functions and basic assert checks, or have equivalent practice.
  • Use an existing Python 3.12+ installation for execution. Each code block is a complete local .py file; run it with python filename.py. No packages, accounts or network are needed.

This is a local testing workshop, not a complete testing strategy or a proof that software has no bugs. The page does not execute Python. All lessons, solutions and offline workbooks are free.

0/4

Completion means practice acknowledged and every quiz answer correct. It is a personal study record, not certification. All lessons remain available.

Loading this device’s progress…

Restore or reset progress

1. Reduce a failure before changing code

By the end

  • Separate the intended contract from the current output.
  • Choose a small counterexample that still exposes the fault.

A useful bug report is a repeatable experiment: exact input, expected behavior, observed behavior and a short way to run it. Start with the rule a person needs, not the formula already in the program. Here a batch holds at most capacity items; empty input needs no batch, and a partly filled final batch counts once.

The proposed formula items // capacity + 1 always adds a batch. For 9 items at capacity 4 it happens to give 3, but for 8 it gives 3 instead of 2. Reducing 8 to 4 preserves the exact-multiple mistake. Reducing again to 0 reveals the related empty-input mistake. Smaller inputs make the unnecessary extra batch easier to see.

Fix the cause and keep the counterexample. Integer ceiling division can use (items + capacity - 1) // capacity for this non-negative integer contract. Validate capacity before division. This lesson rejects booleans intentionally; a Boolean is not a quantity even though Python treats bool as an int subclass. Do not expand the input domain silently while debugging.

Worked example

Compare the broken and repaired count for 0, 1, 4, 5 and 8 items at capacity 4.

  1. Write the expected counts by packing on paper: 0, 1, 1, 2, 2.
  2. Trace integer division for 4: 4 // 4 is 1, so the extra +1 is the fault.
  3. Run both versions, retain checks for 0 and 4, then inspect neighboring 3 and 5 cases.
def batches(items, capacity):
    if type(items) is not int or items < 0:
        raise ValueError("items must be a non-negative integer")
    if type(capacity) is not int or capacity <= 0:
        raise ValueError("capacity must be a positive integer")
    return (items + capacity - 1) // capacity

def broken_batches(items, capacity):
    return items // capacity + 1

for items in (0, 1, 4, 5, 8):
    print(items, broken_batches(items, 4), batches(items, 4))
assert batches(0, 4) == 0
assert batches(4, 4) == 1

The broken counts are [1, 1, 2, 2, 3]; the repaired counts are [0, 1, 1, 2, 2]. The initial formula can pass an ordinary case and still fail a boundary.

Try it yourself

Use capacity 3. Predict and test counts for 0, 2, 3, 4 and 6 items; identify the smallest positive input that exposes the original formula.

  • Write expectations before running the code.
  • Keep the input contract and record one smallest positive counterexample.
Reveal the practice solution

The counts are [0, 1, 1, 2, 2]. At 3 items the broken formula returns 2, although one batch fits them exactly. Inputs 1 and 2 do not expose this fault; 0 exposes the separate empty case.

def batches(items, capacity):
    if type(items) is not int or items < 0:
        raise ValueError("items must be a non-negative integer")
    if type(capacity) is not int or capacity <= 0:
        raise ValueError("capacity must be a positive integer")
    return (items + capacity - 1) // capacity

observed = [batches(n, 3) for n in (0, 2, 3, 4, 6)]
assert observed == [0, 1, 1, 2, 2]
print(observed)

Watch for this mistake: A successful example is evidence for that input, not proof for every input. Do not change an independently justified expected answer to match broken output.

Check your understanding

Choose one answer per question. You can retry without a limit; review the explanation after checking.

1. At capacity 4, what is the smallest positive quantity where items // 4 + 1 is wrong?
2. The test expects 2 batches for 8 items at capacity 4, but the code returns 3. What justifies keeping 2?

0/2 answered. Answer every question before checking.

Sources and review date
  • Python 3.12 — unittest

    TestCase, per-method setUp, subTest, specific exception assertions and running suites. Exercises are original. Checked: .

Explanations, examples and quiz questions are original KitForma material. These links support technical facts and curriculum alignment.

Apply it: your final project

Create three local modules for batch counts, reservation expiry and a dispatch queue, then a test_dispatch.py suite. Keep the worked examples and add one regression for a mistake you deliberately introduce and then repair. Record the failing input, expected result, observed result and cause.

  • Show that 12 items with capacity 4 need 3 batches; test 11 and 13 as neighboring cases.
  • A reservation created at 200 with ttl 30 is valid at 229 and invalid at 230, with one clock read per call.
  • Two queues stay independent; modifying a returned list never changes the queue. Run the test methods individually and in a different order.
  • A deliberately broken implementation must fail the relevant test. A green suite alone does not demonstrate that the tests can detect its target fault.

The project is self-reviewed using this rubric; the site does not automatically grade your code or certify mastery.

KitForma

What would you like to do?