A-Level Computer Science / Unit 12: Software Design, Testing and Evolution

12.3.1 Finding, Preventing and Correcting Program Errors

πŸ”’ Lesson slides are available to signed-in users. Sign in

12.3.1 Finding, Preventing and Correcting Program Errors

Program faults can be introduced while requirements are interpreted, an algorithm is designed or code is written. Some faults prevent translation, some produce an incorrect result and others cause a failure only while the program is running.

Identifying an error type is only the beginning. A developer must gather evidence, locate the underlying fault, correct it and check that the change has not damaged behaviour that previously worked.

By the end of this section, you should be able to:

  • Distinguish between a fault, an error symptom and an observable failure.
  • Identify syntax, logic and run-time errors.
  • Explain how each type of error may be exposed.
  • Suggest ways of reducing the likelihood of faults.
  • Use a systematic debugging process to locate and correct a fault.
  • Explain why corrected code must be retested.

From a Fault to a Program Failure

The words fault, bug and error are often used informally for the same problem. It is useful, however, to distinguish the cause from its observable effect.

Idea Meaning Community-garden example
Fault The underlying mistake in a requirement, design or program statement. The average is divided by one fewer reading than was entered.
Incorrect internal result A value or program state becomes different from what was intended. The calculated average water use is too large.
Failure The observable behaviour no longer meets the requirement. The report displays an incorrect daily average.

A fault does not always produce a visible failure immediately. It may be hidden until a particular input, branch, file, device or operating condition is encountered.

Where faults can enter a project

Development area Original example
Requirements The specification does not state whether an empty set of sensor readings is allowed.
Design The algorithm calculates an average without considering a zero count.
Coding A programmer omits THEN from a selection statement.
Interface The screen does not explain that water values must be entered in litres.
External environment A required sensor file is unavailable when the program runs.
Common misconception: Hardware failure or confusing user input can make a system fail, but they are not automatically program errors. The program fault may be its failure to handle those conditions safely.

Ways of Exposing Faults

Different faults leave different evidence. The developer should collect evidence before changing the code.

Evidence source What it may reveal Example
IDE or translator diagnostic Invalid language structure or an unrecognised token A missing THEN
Expected and actual output A calculation or decision does not match the requirement An expected average of 210 is displayed as 315
Run-time message The operation that failed during execution Division by zero
Variable values The point at which an incorrect value first appears ReadingCount is 1 before dividing by 0
Logs or diagnostic output The last successful action before a failure The program records that opening the sensor file failed
Repeated test The data or condition that reliably triggers the fault The failure occurs whenever exactly one reading is entered
Debugging: the systematic process of locating, understanding, correcting and retesting a program fault.

Dry runs, walkthroughs and trace tables are developed in Section 12.3.2. Later sections examine formal testing methods, release testing and test plans.

Exam tip: Do not say only that an error is β€œfound by testing.” State what evidence would expose it, such as an incorrect expected result, a translator message or a run-time failure with particular data.

Syntax Errors

Syntax error: a program statement that does not follow the grammar rules of the programming language.

A syntax error prevents the affected statement from being translated or executed as valid code. Examples include:

  • a missing keyword;
  • an unclosed bracket or quotation mark;
  • an invalid arrangement of tokens;
  • a misspelled reserved word;
  • an incomplete procedure or selection structure.

Example

IF TotalLitres > ALERT_LIMIT
    OUTPUT "Review irrigation settings"
ENDIF

If this pseudocode convention requires THEN, the condition is incomplete.

How syntax errors are found

Tool or environment Likely behaviour
Code editor or IDE May underline the statement or display a dynamic syntax warning while the code is written.
Compiler Reports syntax problems while translating the source program.
Interpreter May report the problem when parsing or reaching the affected statement.

A diagnostic often identifies where the translator became unable to continue. The real fault may be earlier, such as an unclosed bracket on the preceding line.

Common mistake: The line highlighted by a translator is evidence, not a guaranteed statement of the root cause.
Exam tip: Justify the classification: β€œIt is a syntax error because the statement breaks the required language structure and cannot be translated successfully.”

Logic Errors

Logic error: a fault in the algorithm or reasoning that allows the program to run but causes an incorrect result or behaviour.

A translator checks whether a statement follows language rules. It cannot normally determine whether the statement solves the user's problem correctly.

Example

AverageLitres ← TotalLitres / (ReadingCount - 1)

The statement is structurally valid, but the average should normally be divided by the number of readings.

Logic fault Possible symptom
Incorrect formula A valid-looking but incorrect numeric result
Incorrect comparison operator A boundary value enters the wrong branch
Wrong branch An accepted reading is treated as invalid
Off-by-one loop bound One reading is skipped or processed twice
Incorrect initial value A total begins with an unintended amount

How logic errors are found

Logic faults are exposed by comparing the program's result with a result that has been worked out independently. Values can then be traced to find the first point at which the actual state differs from the expected state.

Common misconception: A program that compiles and finishes without an exception is not necessarily correct.

Run-time Errors

Run-time error: a failure that occurs while the program is executing and prevents it from continuing normally.

The statements may be syntactically valid, but an operation cannot be completed under the current conditions.

Run-time situation Trigger Possible result
Division by zero A divisor becomes zero for a particular input An exception or sudden termination
Unavailable file The requested file does not exist or cannot be opened The file operation fails
Invalid array position An index lies outside the array bounds An exception or memory-access failure
Invalid conversion Text that is not numeric is converted to an integer The conversion fails
Unintended non-terminating loop The loop condition can never become false The program appears to freeze

Run-time faults can be difficult to reproduce because they may require one exact input, file, timing condition or execution path.

Classification note: An unintended infinite loop is caused by incorrect logic, but its visible effect is a run-time freeze. In an exam answer, use the classification expected by the scenario and justify the observed behaviour.
Exam tip: A strong run-time explanation names the triggering condition: β€œThe program fails during execution when ReadingCount is 1 because the divisor becomes zero.”

Comparing the Three Error Types

Feature Syntax error Logic error Run-time error
Main problem Language rules are broken The algorithm or reasoning is wrong An operation fails during execution
Can translation succeed? Not while the detected syntax problem remains Usually yes Usually yes
Can the program begin running? Not normally beyond the affected code Yes Yes, until the triggering condition occurs
Typical symptom Translator diagnostic Incorrect output or decision Exception, crash or freeze
Useful evidence Diagnostic location and message Expected versus actual values Triggering data and run-time message
Typical correction Repair the invalid statement structure Repair the algorithm or condition Prevent or safely handle the invalid operation

One fault can produce different symptoms

Consider:

AverageLitres ← TotalLitres / (ReadingCount - 1)
  • With four readings, the line runs but produces a wrong average: a logic failure.
  • With one reading, the divisor is zero and execution may stop: a run-time failure.

The underlying algorithmic fault is the same, but the observed symptom depends on the input.

Exam tip: Classify the error described by the question, then justify the classification using what happens during translation or execution.

Preventing Errors Before They Occur

Testing is necessary, but preventing faults during analysis, design and coding is usually more effective than relying on later correction.

Preventive action How it reduces faults Irrigation-report example
Clarify requirements Removes uncertainty before the algorithm is designed. Specify whether zero readings are allowed.
Define expected results Provides evidence against which the program can be checked. Specify how the average and alert threshold should work.
Use structured design Breaks a complex solution into understandable modules. Separate input, calculation and report output.
Use an identifier table Clarifies data types, purposes and valid ranges. Define ReadingCount as a positive integer.
Use meaningful identifiers Makes incorrect uses easier to notice. AverageLitres is clearer than X.
Use named constants Avoids unexplained repeated values and inconsistent edits. ALERT_LIMIT replaces a repeated literal value.
Use established algorithms and components Reduces the amount of untested new logic. Reuse a tested file-reading routine.
Validate assumptions Prevents invalid data from reaching unsafe operations. Reject a reading count below 1 before division.
Keep modules focused Makes reasoning, testing and correction more manageable. Place average calculation in one small function.
Review work early Exposes misunderstandings before they spread through the program. Check the formula against a manually calculated example.
Common misconception: Prevention does not mean that testing can be removed. Good design reduces risk; testing supplies evidence about the implemented program.

A Systematic Debugging Cycle

  1. Observe the failure. Record what happened, the input used and the expected result.
  2. Reproduce it. Repeat the same conditions to confirm that the failure is consistent.
  3. Reduce the problem. Identify the smallest input, module or execution path that still fails.
  4. Locate the divergence. Find where the actual value or control path first differs from the expected one.
  5. Explain the cause. Determine why the statement produces the failure.
  6. Correct the root fault. Change the requirement, design or statement responsible for the problem.
  7. Retest the original case. Confirm that the reported failure has been removed.
  8. Run related tests. Check that the change has not introduced another fault.
  9. Record the correction. Document the cause and the amended behaviour where appropriate.
Root cause: the underlying fault that produces one or more observable symptoms.
Common mistake: Changing several unrelated statements at the same time makes it difficult to know which change corrected the problem or introduced a new one.

Correct the Cause, Not Only the Symptom

A correction should restore the required behaviour for all relevant cases. Hiding one symptom is not enough.

Weak response Why it is weak Stronger correction
If division fails, display an average of 0. It hides the exception but may display a false result. Reject an invalid count and divide a valid total by the correct count.
Remove the alert condition because it reports the wrong plots. It removes required functionality. Correct the comparison and retain the intended alert.
Ignore a missing sensor file. Later calculations may use no data or stale data. Check availability and give a controlled response when the file cannot be opened.
Change several formulas until one result looks right. The code is not being corrected from evidence. Derive the intended formula independently and amend the identified fault.
Exam tip: When asked to correct an error, show the amended statement and explain why it now satisfies the requirement.

Worked Example: Community-Garden Water Report

A program reads daily water-use measurements. It should reject a count below 1, calculate the average and display an alert when the total exceeds 900 litres.

Faulty pseudocode

PROCEDURE ProduceWaterUseReport
    DECLARE ReadingCount : INTEGER
    DECLARE Index : INTEGER
    DECLARE DailyLitres : REAL
    DECLARE TotalLitres : REAL
    DECLARE AverageLitres : REAL

    CONSTANT ALERT_LIMIT = 900.0

    TotalLitres ← 0

    OUTPUT "Number of readings:"
    INPUT ReadingCount

    IF ReadingCount < 0 THEN
        OUTPUT "At least one reading is required"
    ELSE
        FOR Index ← 1 TO ReadingCount
            INPUT DailyLitres
            TotalLitres ← TotalLitres + DailyLitres
        NEXT Index

        AverageLitres ← TotalLitres / (ReadingCount - 1)

        IF TotalLitres > ALERT_LIMIT
            OUTPUT "Review irrigation settings"
        ENDIF

        OUTPUT "Average: ", AverageLitres
    ENDIF
ENDPROCEDURE

Fault 1: incomplete selection syntax

Evidence Diagnosis Correction
The translator expects another keyword after the condition. Syntax error: THEN is missing. IF TotalLitres > ALERT_LIMIT THEN

Fault 2: invalid count accepted

Evidence Diagnosis Correction
A count of 0 enters the calculation branch. Logic error: the boundary condition does not match the requirement. Replace ReadingCount < 0 with ReadingCount < 1.

Fault 3: incorrect divisor

Input condition Observed symptom Diagnosis
Three or more readings The average is too large. Logic failure caused by the wrong formula.
Exactly one reading The divisor becomes zero. Run-time failure triggered by the same faulty formula.

The correction is:

AverageLitres ← TotalLitres / ReadingCount

Corrected pseudocode

PROCEDURE ProduceWaterUseReport
    DECLARE ReadingCount : INTEGER
    DECLARE Index : INTEGER
    DECLARE DailyLitres : REAL
    DECLARE TotalLitres : REAL
    DECLARE AverageLitres : REAL

    CONSTANT ALERT_LIMIT = 900.0

    TotalLitres ← 0

    OUTPUT "Number of readings:"
    INPUT ReadingCount

    IF ReadingCount < 1 THEN
        OUTPUT "At least one reading is required"
    ELSE
        FOR Index ← 1 TO ReadingCount
            INPUT DailyLitres
            TotalLitres ← TotalLitres + DailyLitres
        NEXT Index

        AverageLitres ← TotalLitres / ReadingCount

        IF TotalLitres > ALERT_LIMIT THEN
            OUTPUT "Review irrigation settings"
        ENDIF

        OUTPUT "Average: ", AverageLitres
    ENDIF
ENDPROCEDURE
Exam tip: Notice the order of correction. The syntax fault must be repaired before the program can be executed normally, but logic and run-time faults may still remain afterwards.

Retesting After a Correction

Regression testing: repeating relevant tests after a change to check that existing behaviour still works.

The original failing case must be repeated, but that test alone is insufficient. Related values and branches should also be checked.

Input Expected result Purpose
ReadingCount = 0 The program rejects the count. Checks the corrected lower boundary.
One reading: 155 Average is 155. Checks that division by zero no longer occurs.
Three readings: 210, 180, 240 Average is 210; no alert. Checks the corrected formula.
Two readings: 520, 430 Average is 475; alert is displayed. Checks the alert branch after the correction.
Total exactly 900 No alert if the requirement says β€œexceeds 900”. Checks the comparison boundary.

The later test-plan page develops formal categories of test data and expected-result documentation in more detail.

Common mistake: A successful retest of the reported failure does not show that every related behaviour remains correct.

Interactive: Diagnose, Correct and Retest

Choose a faulty scenario, classify it and then move through the debugging cycle. The widget shows how the same evidence leads from an observed symptom to a correction and a prevention strategy.

Fault scenario Missing selection keyword
IF TotalLitres > ALERT_LIMIT
    OUTPUT "Review irrigation settings"
ENDIF

The translator reports that the selection statement is incomplete.

Choose the most appropriate error type

Select an error type to begin the diagnosis.
Observe
Locate
Correct
Retest

Current evidence

The program cannot translate the incomplete selection statement.

Suggested correction

Classify the fault first to reveal the correction.

Prevention idea

Classify the fault first to reveal a prevention strategy.

Common Mistakes and Misconceptions

  • Calling every problem a syntax error. Syntax errors break language rules; logic and run-time errors can remain after successful translation.
  • Assuming successful compilation proves correctness. Compilation does not prove that the algorithm meets its requirements.
  • Assuming a run-time error happens every time. It may require one particular input or execution path.
  • Changing code before reproducing the failure. Important evidence may be lost.
  • Correcting the visible symptom only. The underlying fault may still affect other cases.
  • Changing several unrelated statements together. This makes the effect of each change unclear.
  • Retesting only the original failing value. Related paths may have been damaged by the correction.
  • Saying testing proves that no faults remain. Testing increases confidence by exposing faults under the tested conditions.
  • Ignoring errors in requirements and design. Correct syntax cannot repair a misunderstood requirement.

Practice

Core questions

  1. Distinguish between an underlying fault and an observable failure.
  2. Define a syntax error and explain how it may be exposed.
  3. Define a logic error and explain how it may be exposed.
  4. Define a run-time error and explain how it may be exposed.
  5. Explain why a translator cannot normally identify an incorrect formula.
  6. Give four ways in which faults can be prevented or reduced.
  7. Explain why a reported failure should be reproduced before code is changed.
  8. Explain why regression testing is needed after a correction.

Scenario A: Air-Quality Summary

A program reads hourly pollution measurements and calculates their mean. It contains this statement:

MeanReading ← TotalReading / (HourCount + 1)
  1. Identify the most likely error type when the program displays a wrong mean.
  2. Explain how you would expose the fault using expected results.
  3. Write the corrected statement.
  4. Suggest two related values that should be retested.
  5. Suggest one design practice that could have prevented the fault.

Scenario B: File Import

A program works correctly in the developer's folder but stops when a user runs it on another computer because observations.txt is unavailable.

  1. Identify the observed error type.
  2. State the condition that triggers the failure.
  3. Suggest how the program should respond safely.
  4. Explain how the correction should be retested.
  5. Explain why changing the filename without investigating is a weak response.

Scenario C: Two Faults in One Program

IF Score >= 60
    Grade ← "Pass"
ELSE
    Grade ← "Fail"
ENDIF

The language requires THEN. The requirement also says that a score of exactly 60 should be classified as "Review".

  1. Identify the syntax fault.
  2. Explain why correcting it does not make the algorithm correct.
  3. Identify the remaining logic fault.
  4. Rewrite the selection to meet the requirement.
  5. Suggest suitable values to retest around the boundary.
Challenge: Write a debugging record containing the symptom, triggering input, identified cause, correction and regression tests for one practice scenario.

Review

Prompt A strong response should include
Syntax error A statement breaks language rules and is exposed by an editor or translator.
Logic error The program can run, but its result or control behaviour is incorrect.
Run-time error A failure occurs during execution under particular conditions.
Finding a fault Collect evidence, reproduce the problem and locate the first incorrect value or path.
Preventing faults Clear requirements, structured design, conventions, validation and tested components.
Correcting a fault Repair the underlying cause and preserve the required behaviour.
Retesting Repeat the original failure and related tests after the change.
Final exam tip: Use the chain symptom β†’ evidence β†’ error type β†’ root cause β†’ correction β†’ retest.