English:Systematic testing and logical debugging in Python - Computing Year 6
Introduction

A program can run without stopping and still give the wrong answer. Learn to turn a written requirement into a test plan, locate the first incorrect decision or total, make a small repair and demonstrate a successful retest.
Starting point: You can read Python assignments, comparisons and a finite for loop. The earlier Python decisions, loops and simple simulations - Computing Year 6 provides useful practice. This Year 6 Python route is editorial within key stage 2 programming and debugging, not a statutory requirement to use a specific language in this year.
Your evidence: A saved faulty version, predicted and actual test results, a corrected version and regression results. You will test a number classifier, trace a running total and transfer the method to an invented score threshold. None of the scores are real pupil records or qualification results.
Use a teacher-approved Python 3 environment. All examples use invented data and local printed output; no package installation, online account, external service or hardware is required. Keep personal data and private file paths out of shared evidence. If you can only trace on paper, record execution as pending rather than claiming the program has been run.
Build a test plan from the specification
Start with a specification: a statement of required behaviour. Our first program receives an integer from -10 to 10 inclusive. It must report "negative" below zero and "zero or positive" at zero or above. These two labels deliberately place zero in the second group. Zero is neither positive nor negative, but it belongs in the combined category called zero or positive.
An expected result comes from that rule before you inspect the program's answer. Otherwise a plausible-looking wrong result may persuade you to change the test rather than fix the fault.
| Input | Expected result | Test purpose |
|---|---|---|
| -4 | negative | Ordinary negative input |
| 6 | zero or positive | Ordinary positive input |
| -1 | negative | Immediately below the decision boundary |
| 0 | zero or positive | Exactly at the decision boundary |
| 1 | zero or positive | Immediately above the decision boundary |
Normal tests use ordinary permitted inputs. Boundary tests examine an edge or change point: here -1, 0 and 1 surround the classification change. The allowed input range also has edges at -10 and 10, which deserve checks. Test purpose matters more than attaching one exclusive label to each number; a valid boundary value can also be a normal permitted input.
Separate logic tests from input validation
The classifier's contract supplies valid integers. It does not promise to reject text, missing input or arbitrary objects. Testing "hello" would investigate an extension outside that contract. Record this limitation, and specify new validation behaviour before adding such a feature. Do not quietly claim that a simple comparison function handles every possible kind of input.
Add columns for actual result, PASS or FAIL and notes. A test passes when the observed result matches the expectation derived from the specification. One passing case is useful evidence for that case, not proof of all possible behaviour. A failing case is useful too: it gives a concrete starting point for debugging.
Try first: Predict the categories for -10, -1, 0, 1 and 10. Expected: negative, negative, zero or positive, zero or positive, zero or positive. Explain the zero case in words before reading any code.
Find and repair a boundary comparison fault
A logic error can produce an incorrect answer with no syntax failure. The following complete program is deliberately faulty. Save it as a separate learning copy, predict the three results and run it.
def classify(number):
if number > 0:
return "zero or positive"
else:
return "negative"
tests = [(-1, "negative"), (0, "zero or positive"), (1, "zero or positive")]
for number, expected in tests:
actual = classify(number)
if actual == expected:
result = "PASS"
else:
result = "FAIL"
print(number, "expected:", expected, "actual:", actual, result)
Read the function and test loop
def classify(number): defines a small reusable function. When the loop calls classify(number), that input becomes the function's local number. return sends the chosen label back to the caller. The function does not print its own result; the test loop stores the returned label as actual and prints the comparison.
Each tuple in tests pairs an input with its predetermined expected label. The loop unpacks those two values. The == comparison checks whether actual equals expected; it does not assign a new value. The PASS and FAIL words are software test results, not judgements about the learner.
The supplied tests produce PASS, FAIL, PASS. At input 0, the program actually returns negative although the contract requires zero or positive. Trace the first decision: 0 > 0 is false, so the else branch is chosen. The first wrong decision is now identified precisely.
Repair hypothesis: Include zero in the first branch by changing > to >=. Change only that comparison; keep the specification and expected test labels unchanged. Here is the complete corrected version:
def classify(number):
if number >= 0:
return "zero or positive"
else:
return "negative"
tests = [(-1, "negative"), (0, "zero or positive"), (1, "zero or positive")]
for number, expected in tests:
actual = classify(number)
if actual == expected:
result = "PASS"
else:
result = "FAIL"
print(number, "expected:", expected, "actual:", actual, result)Run it and retain the old failing evidence. All three rows should now print PASS. Then test -4, 6, -10 and 10 too. Repeating earlier successful cases after the repair checks for regression: a change that fixes one case must not break another requirement.
Explain the repair: The fault was not that Python misunderstood zero. The program expressed the wrong condition. Replacing the expected zero label with negative would hide the mismatch while leaving the specification unmet.
Optional view of professional testing
CS50's original unit-testing lecture shows why programmers test their programs. A teacher may choose a short introductory demonstration of an expected result and a failed test. The full university-length lecture, its testing framework and package installation are not required here. Compare its testing idea with our plain Python loop; all work in this course can be completed from the written examples.
Trace an accumulator and preserve earlier totals
Trace intermediate values, not only the final line. Our next contract is to add a finite list of non-negative integer token counts, print the running total after each item and print the final total. The empty list should give final total 0. The inputs are invented counts, not money or real orders.
For [3, 4, 2], the correct running totals are 3, 7 and 9. Predict the result of this deliberately faulty program:
values = [3, 4, 2]
total = 0
for value in values:
total = 0
total = total + value
print("value:", value, "running total:", total)
print("final total:", total)It prints running totals 3, 4 and 2, then final total 2. The first row happens to be correct. The first discrepancy appears on the second row, where expected 7 becomes actual 4. A test with just one positive item would fail to reveal this bug.
| Item | Value | Correct total before addition | Correct total after addition | Faulty total after addition |
|---|---|---|---|---|
| 1 | 3 | 0 | 3 | 3 |
| 2 | 4 | 3 | 7 | 4 |
| 3 | 2 | 7 | 9 | 2 |
The inner total = 0 erases the accumulated value on every iteration. Moving your attention to the final print statement alone would miss the cause. Keep the initial zero before the loop and remove only the repeated reset:
values = [3, 4, 2]
total = 0
for value in values:
total = total + value
print("value:", value, "running total:", total)
print("final total:", total)
Choose tests that can distinguish the versions
Run the empty list: final total 0, no running-total rows. Run [5]: running and final total 5. Run [0, 0, 0]: three zero running totals and final zero. These are worthwhile cases, but both versions pass them. They do not distinguish the reset fault.
Now run [5, 0, 2]. Correct running totals are 5, 5 and 7; the faulty ones are 5, 0 and 2. This test checks that a zero item preserves an earlier total instead of erasing it. Record actual output for both versions and explain the first mismatch.
A disciplined debugging cycle: Reproduce the failure with a small input list, trace the changing variable, form one explanation, make one targeted edit and retest. Once the new results match, rerun the earlier cases too. Do not remove a revealing test just because it produces FAIL in the old version.

Transfer the method and document reliable evidence
Transfer the method to a new contract. An invented practice score is an integer from 0 to 100 inclusive. The result must be "pass" for scores of 50 or more and "not yet" below 50. This is a fictional coding rule, not an actual examination grading scheme.
Design expected outcomes before implementing the comparison. Include an ordinary lower score such as 20, an ordinary higher score such as 70, the decision cases 49, 50 and 51, and the permitted endpoints 0 and 100. Expected labels are not yet at 0, 20 and 49, and pass at 50, 51, 70 and 100.
def outcome(score):
if score >= 50:
return "pass"
else:
return "not yet"
tests = [(0, "not yet"), (49, "not yet"), (50, "pass"), (51, "pass"), (70, "pass"), (100, "pass")]
for score, expected in tests:
actual = outcome(score)
print(score, "expected:", expected, "actual:", actual, actual == expected)Every printed final Boolean should be True for this corrected version. In a separate faulty copy, replace >= 50 with > 50. The row for 50 should print False while the other supplied rows still print True. Restore the intended comparison, rerun the same tests and retain before-and-after evidence. This controlled fault is a learning exercise; never make such changes to a real grading system.
Keep evidence that someone else can reproduce
Use a small test report with these fields:
- The exact contract, including input assumptions and threshold.
- A version label such as faulty-v1 or corrected-v2, plus the saved program.
- Test purpose, input and expected output written before the run.
- Actual result and whether it matches, copied accurately.
- The first incorrect decision or changing value in a failed trace.
- The single repair and retest results, including earlier working cases.
Ask a peer to reproduce one normal test and the exact-boundary test using your corrected file. If their result differs, compare versions and input data first. Test evidence is useful only when the tested program and conditions are clear.
Distinguish fault types and avoid overclaiming
A syntax error means the program's structure is not valid Python, for example a missing colon after an if line. A runtime error occurs during execution, for example attempting an unsupported comparison between unsuitable input types. A logic error can allow the program to complete while returning a result that fails its specification. The supplied comparison and reset faults are logic errors.
Passing these tests supports the tested contracts. It does not certify arbitrary inputs or prove the absence of every possible bug. The classifier and score function assume valid integers; the running-total example assumes a list of non-negative integers. A robust-input extension needs a stated rejection policy and its own tests.
Stretch choice: Change the fictional score threshold to 60 in a copy, update the specification and expected labels first, then test 59, 60 and 61. Expected: not yet, pass, pass. Explain why changing expectations is legitimate when the requirement has deliberately changed, but not when hiding a defect under an unchanged requirement.
Interactive Tasks
Quiz: Test Your Knowledge
Where should the expected result of a test come from? (The stated specification before observing the actual result) (!Whatever the current program happens to print) (!The most popular answer in the class) (!A random replacement after each failed run)
The classifier must return zero or positive at zero. What is wrong with using number > 0 for that branch? (It excludes zero from the required branch) (!It includes every negative number) (!It prevents the function from returning text) (!It changes zero into a positive integer)
Which three inputs directly surround the classifier's decision boundary? (Minus one, zero and one) (!Two, four and six) (!Seven, eight and nine) (!Minus ten, minus eight and minus six)
The faulty classifier passes at -1 and 1 but fails at 0. Which targeted repair matches the contract? (Include equality in the zero-or-positive comparison) (!Change the expected label at zero to negative) (!Remove zero from the test table) (!Replace all outputs with a single constant label)
For the running-total list 3, 4, 2, what are the correct totals after each item? (3, 7, 9) (!3, 4, 2) (!0, 0, 0) (!9, 9, 9)
Why can resetting total to zero inside the loop produce a logic error? (It erases the accumulated value before each addition) (!It adds every value twice) (!It makes the list infinite) (!It changes every integer into text)
Which test best distinguishes the repeated-reset fault from the corrected running-total program? (A list with several values whose earlier sum matters) (!Only an empty list) (!Only a single item with value five) (!Only a list of three zero values)
What is regression testing after a repair? (Repeating earlier tests to check that working behaviour is preserved) (!Deleting every test that previously passed) (!Changing the specification to match a faulty answer) (!Assuming no other case can be affected)
Under the fictional score rule, 50 or more means pass. What should scores 49, 50 and 51 produce? (Not yet, pass, pass) (!Not yet, not yet, pass) (!Pass, pass, pass) (!Pass, not yet, not yet)
Which claim is justified after these practical tests pass? (The tested cases match the declared contracts in the tested version) (!Every possible input is now safe forever) (!The program is certified for real examination grading) (!There is no need to retain code or actual results)
Memory Game
| Specification | A statement of the required program behaviour |
| Expected result | The answer predicted from the contract before a run |
| Actual result | The behaviour observed during execution |
| Logic error | A program can run but fail its stated requirement |
| Boundary test | Examines a change point or permitted edge value |
| Regression test | Repeats earlier cases after a change |
Drag and Drop
| Plan | Write the input, purpose and expected result |
| Run | Execute the saved version with the recorded input |
| Compare | Check the observed result against the prediction |
| Repair | Change the identified cause while retaining the contract |
| Retest | Repeat the failed case and earlier working cases |
Crossword Puzzle
| SPECIFICATION | The required behaviour used to judge correctness |
| BOUNDARY | A change point worth testing exactly |
| TRACE | A step-by-step record of changing values |
| ACTUAL | The result observed when the program runs |
| REPAIR | A targeted correction of an identified fault |
| REGRESSION | Testing earlier behaviour again after a change |
LearningApps
Optional extra practice. Choose an appropriate activity with your teacher. If the external collection is unavailable, use the native activities and independent tasks in this course.
Cloze Text
Open Tasks
Easy
- Test plan vocabulary: Explain specification, expected result and actual result with the zero test. Solution: the rule puts zero in zero or positive; that is the expectation; the observed returned label is the actual result.
- Classifier boundary prediction: Classify -1, 0 and 1 without running the program. Solution: negative, zero or positive, zero or positive. Explain why zero needs an explicit boundary test.
- Running-total paper trace: Trace the correct totals for 3, 4, 2. Solution: start at 0, then obtain 3, 7 and 9. State that a paper trace is a prediction rather than evidence of execution.
- Expected versus observed evidence: A test expects zero or positive at 0 but the program returns negative. Identify the test result and the next useful action. Solution: FAIL; inspect the decision at zero and retain the failing evidence.
Standard
- Execute and repair the classifier: Run the faulty classifier with the supplied three tests, save the evidence, repair only the comparison and rerun. Expected old results: PASS, FAIL, PASS. Expected corrected results: PASS, PASS, PASS. Explain the >= boundary change.
- Normal and boundary testing plan: Prepare a test plan with ordinary inputs -4 and 6 plus -1, 0 and 1 and endpoints -10 and 10. Derive every expected label first, then record actual corrected-program results. Solution: only negative values get negative; zero and all positive values get zero or positive.
- Locate the first incorrect running total: Run both total programs on 3, 4, 2 and compare each row. Solution: row 1 matches; row 2 first differs, 4 instead of 7. The inner zero assignment erases the previous total.
- Document a regression retest: After repairing the total program, run the empty list, a single 5 and the list 5, 0, 2. Expected final totals: 0, 5 and 7; the last running trace is 5, 5, 7. Keep purpose, predictions, actual results and version labels.
Advanced
- Fictional score debugging transfer: Write the expected labels for 49, 50 and 51, demonstrate the > 50 fault in a copy and repair it. Solution: not yet, pass, pass; the faulty version rejects exactly 50 among these cases, and >= 50 fixes that boundary.
- A test that cannot reveal the bug: Explain why an empty list, a one-item list and an all-zero list can pass even with the repeated-reset fault. Add a discriminating case. Solution: no retained earlier nonzero amount is needed in those cases; 5, 0, 2 reveals the lost total.
- Changed specification versus hidden fault: Change the fictional score threshold to 60 and justify revised tests at 59, 60 and 61. Solution: not yet, pass, pass. Contrast this deliberate new requirement with changing a failing expected result while keeping the old requirement.
- Reproducible debugging review: Give a peer the exact corrected file, contract and expected tests. Ask them to reproduce one normal and one boundary case. Record differences and explain one input-validation limitation. Solution guide: compare versions and inputs before editing; these examples assume valid integer data and do not claim arbitrary-input handling.
Learning Check
- Zero boundary assessment: Explain the fault in number > 0 when zero belongs in zero or positive. Give a repair and three tests.
- Accumulator trace assessment: Give the expected and faulty running totals for 3, 4, 2 when total is reset inside the loop. Locate the first mismatch.
- Testing purpose assessment: Explain why testing 6 alone is insufficient evidence for the classifier and add useful cases.
- Score threshold assessment: The fictional rule is pass at 50 or more. Predict results for 20, 49, 50, 51 and 70 and explain the repair for a > 50 fault.
- Debugging artefact assessment: Submit a test plan, actual failing evidence, a trace locating the cause, a targeted correction and regression results for a supplied program.
- Evidence limitation assessment: What can you conclude after every chosen test passes? Name a claim you cannot make.
Worked checks and assessment guidance
- The strict greater-than condition excludes zero. Use number >= 0; test -1, 0 and 1 with expected labels negative, zero or positive, zero or positive.
- Expected: 3, 7, 9. Faulty: 3, 4, 2. The first mismatch is at the second addition; repeated initialisation erases the previous 3. Initialise once before the loop.
- The > 0 fault still returns the required label at 6. Add zero and its neighbours -1 and 1, plus a normal negative input and permitted range endpoints. Test selection should exercise different requirements.
- Expected: not yet, not yet, pass, pass, pass. Include equality by using >= 50. Keep the expected labels and rerun all tests, including previously passing cases.
- Require at least one ordinary permitted input and boundary cases with predictions derived from the specification. Confirm saved runnable code and actual execution separately from paper reasoning. The report must preserve the failing observation and show that the corrected version matches the unchanged contract.
- The tested version matches the stated expectations for the tested cases. You cannot conclude that every possible input or future change is correct, or that these fictional examples are approved for real-world grading. Record valid-input assumptions.
Learning evidence
Knowledge: Distinguish specification, expected and actual result, boundary test, logic error and regression test.
Practical artefact: Save and run a supplied faulty Python program and a corrected version. Preserve the old failure, a trace locating its cause and actual retest results.
Test plan: Include a normal permitted input, exact-boundary and neighbouring values where relevant, purpose and predetermined expectations. Add the accumulator's discriminating multi-item case when assessing that program.
Transfer: Apply the method to the fictional score comparison or a deliberately changed threshold, documenting the new contract.
Completion distinction: Knowledge quiz scores do not prove execution. If only paper predictions are available, retain practical execution as pending. The invented values are not real pupil records; no operational grading system is involved.
OER and Wikipedia
Department for Education: Computing programmes of study, key stage 2. Logical reasoning and debugging inform this editorial Year 6 sequence; neither this precise annual placement nor Python is a statutory year-specific requirement. All contracts, teaching programs, traces and task examples here are original course material.
Language reference: Python Software Foundation: More control flow tools, for comparisons, if, for and defining functions. Testing context: CS50 Python, Week 5: Unit Tests, original course resource and optional film. This course needs only basic Python and printed comparisons, not the lecture's optional packages.
Photographs, unmodified: Rubber duck assisting with debugging, Tom Morris, CC BY-SA 3.0; Python Code, Weal2019, CC0. The first photograph contains Java, and the second is a different Python example; neither is the supplied exercise program.
Video: CS50P, Lecture 5: Unit Tests, CS50 / Harvard, original publisher's YouTube embed. A short teacher-selected introductory example is optional; the full university-length lecture and framework installation are not required. No film copy or adaptation is supplied.
Linked learning areas
aiMOOC Projects
Schulfach+


aiMOOCs


aiMOOC Projekte


MOOCwiki · Deutsch
Nach dem Lernen ist vor dem Lernen
Entdecke direkt den nächsten Lernkurs. Weitere Inhalte erscheinen, wenn Du weiter nach unten scrollst.
Zur MOOCwiki-HauptseiteMediathek
Mediathek wird aus dem Wiki geladen ...
Keine passenden Inhalte gefunden. Bitte ändere Suche oder Filter.
NEWSLernweltNOAH fragen