📑 Contents

Chapter 12.3: Program Testing & Maintenance

9618 AS Computer Science

📚 Learning Objectives
🌟 Did You Know?

Research has shown that the earlier an error can be found, the cheaper it is to fix it. Testing software before release is essential, but testing throughout development is even more critical. The purpose of testing is to discover errors — program testing can show the presence of bugs, but never to show their absence!

1. Faults and Errors in Programs

Most programs written will contain errors, as programmers are human and do make mistakes. A program fault is something that makes a program not do what it is supposed to do under certain circumstances.

📖 Key Terms

1.1 Fault Avoidance

Fault avoidance starts with provision of comprehensive and rigorous program specification at the end of analysis phase, followed by use of formal methods:

📝 Fault Prevention Methods
⚠️ Important

Testing will show presence of faults to be corrected, but cannot guarantee that programs are fault-free under all circumstances. Faults can appear during the lifetime of a program and may be exposed during live running.

1.2 Why Errors Occur

Software may not perform as expected for a number of reasons:

Source of Error Description
Programmer mistake Coding errors made during development
Requirement specification Specification not drawn up correctly
Design error Software designer made a design error
User interface Poorly designed interface causes user mistakes
Hardware failure Computer hardware experiences failure
SYNTAX LOGIC RUN-TIME IDEs help detect syntax errors | Testing finds logic errors | Exception handling catches run-time errors (Grammar errors) .................. (Wrong results) .................. (Program crashes)

2. Syntax Errors

Syntax errors are errors in the grammar of a source program. A syntax error occurs when a program statement does not follow the rules of the programming language, for example, incorrect spelling of a keyword.

📖 What are Syntax Errors?

2.1 Common Syntax Errors

Error Type Example
Typos and spelling errors PRINNT instead of PRINT
Missing or extra brackets IF (x > 5 THEN (missing closing bracket)
Missing quotes OUTPUT "Hello (missing closing quote)
Misplaced/missing semicolons In languages that require them
Invalid variable names Using reserved keywords as variable names
Incorrect use of operators Using = instead of ← for assignment
Incorrectly nested loops Mismatched IF/ENDIF, WHILE/ENDWHILE
❌ Pseudocode WITH Syntax Errors:
FUNCTION generate_username(first_name STRING, last_name STRING) RETURNS STRING
    DECLARE username : STRING
    username = SUBSTRING(first_name, 1, 1) + SUBSTRING(last_name, 1, 1)
    RETURN username
ENDFUNCTION

PROCEDURE main()
    OUTPUT "Enter your first name: "
    INPUT first_name
    username ← generate_username[first_name, last_name]  // Wrong brackets!
ENDPROCEDURE

CALL Main  // Wrong capitalization and missing ()
✅ Pseudocode WITHOUT Syntax Errors:
FUNCTION generate_username(first_name : STRING, last_name : STRING) RETURNS STRING
    DECLARE username : STRING
    username ← SUBSTRING(first_name, 1, 1) + SUBSTRING(last_name, 1, 1)
    RETURN username
ENDFUNCTION

PROCEDURE main()
    OUTPUT "Enter your first name: "
    INPUT first_name
    username ← generate_username(first_name, last_name)  // Correct!
ENDPROCEDURE

CALL main()  // Correct!
💡 Exam Tip

Syntax errors are usually detected by the compiler or interpreter before the program runs. If your program won't even start, check for syntax errors first!

3. Logic Errors

Logic errors are errors in the logic of a program, meaning the program does not do what it is supposed to do. The program runs, but produces incorrect output or results. These errors are usually found when the program is being tested.

📖 What are Logic Errors?

3.1 Common Logic Errors

Error Type Example Correct Version
Wrong operator IF x > 0 OR y > 0 IF x > 0 AND y > 0
Wrong arithmetic area ← width - length area ← length * width
Loop one extra time FOR i = 0 TO 10 FOR i = 0 TO 9
Array index off by one Accessing index 5 in array[0..4] Access index 0 to 4 only
Using uninitialized variables Using count before setting to 0 Initialize: count ← 0
Infinite loops WHILE x > 0 (x never changes) Ensure x changes in loop
❌ Pseudocode WITH Logic Errors:
FUNCTION calculate_area(length : REAL, width : REAL) RETURNS REAL
    // Checks for valid dimensions and calculates area
    IF length > 0 OR width > 0 THEN  // Wrong: allows negatives!
        DECLARE area : REAL
        area ← width - length  // Wrong: subtraction instead of multiplication!
        RETURN area
    ELSE
        OUTPUT "Length and width must be positive values."
    ENDIF
ENDFUNCTION
✅ Pseudocode WITHOUT Logic Errors:
FUNCTION calculate_area(length : REAL, width : REAL) RETURNS REAL
    // Checks for valid dimensions and calculates area
    IF length > 0 AND width > 0 THEN  // Correct: both must be positive
        DECLARE area : REAL
        area ← length * width  // Correct: multiplication for area
        RETURN area
    ELSE
        OUTPUT "Length and width must be positive values."
    ENDIF
ENDFUNCTION
📝 How to Find Logic Errors
  1. Use trace tables to dry-run the program step by step
  2. IDEs allow us to single-step through a program
  3. Check values of each variable as they change
  4. Compare expected output with actual output
  5. Test with known input values and verify results

4. Run-Time Errors

Run-time errors happen when a program executes an invalid instruction, encounters an out of bounds error, or attempts to divide by zero. The program may halt unexpectedly or go into an infinite loop.

📖 What are Run-Time Errors?

4.1 Common Run-Time Errors

Error Type Example Prevention
Division by zero result ← x / 0 Check divisor ≠ 0 before division
Array index out of bounds Accessing array[10] when array is size 5 Validate index before access
File not found Opening non-existent file Check file exists before opening
Memory overflow Infinite recursion Set recursion limits
Type mismatch Adding string to number Validate data types
Null pointer reference Accessing uninitialized object Check for null before access
❌ Pseudocode WITH Run-Time Error:
FUNCTION divide_numbers(a : REAL, b : REAL) RETURNS REAL
    DECLARE result : REAL
    result ← a / b  // Will crash if b = 0!
    RETURN result
ENDFUNCTION

// Calling with b = 0 causes run-time error
answer ← divide_numbers(10, 0)  // CRASH!
✅ Pseudocode WITH Exception Handling:
FUNCTION divide_numbers(a : REAL, b : REAL) RETURNS REAL
    DECLARE result : REAL
    IF b = 0 THEN
        OUTPUT "Error: Cannot divide by zero!"
        RETURN -1  // Return error code
    ELSE
        result ← a / b
        RETURN result
    ENDIF
ENDFUNCTION

// Safe calling
answer ← divide_numbers(10, 0)  // Returns -1 with error message
💡 Exam Tip

The key difference: Syntax errors prevent the program from running, Logic errors allow program to run but produce wrong results, Run-time errors cause program to crash during execution.

SYNTAX Program won't compile Grammar rules broken Found by compiler ⚠ Easiest to find LOGIC Program runs but... Wrong results! Found by testing 🔍 Use trace tables RUN-TIME Program crashes during execution Div by 0, out of bounds 🛡 Exception handling

5. Testing Methods

Programs need to be tested before they are released. Tests begin from the moment they are written; they should be documented to show that the program is robust and ready for general use.

📖 Key Principle

The purpose of testing is to discover errors. Program testing can be used to show the presence of bugs, but never to show their absence. Testing takes place during the testing stage of the program development life cycle.

5.1 Dry Run / Walkthrough

A dry run (also called a walkthrough) involves manually tracing through the code on paper to predict output and track variables. This is done using a trace table.

📝 How to Dry Run
  1. Write down current contents of all variables
  2. Track conditional values at each step
  3. Use different test data to verify algorithm
  4. Compare expected output with actual output

5.2 Stub Testing

Stub testing is employed during development of modular programs, conducted before all modules have been fully implemented.

📖 Stub Testing Features

5.3 White-Box Testing

White-box testing tests the internal logic and code structure. The tester knows how the program works and chooses suitable test data that checks every path through the code.

Example: If a program has multiple IF statements, white-box testing ensures every branch (both TRUE and FALSE paths) is tested at least once.

5.4 Black-Box Testing

Black-box testing focuses on functionality of software without considering its internal code structure. Testers do not have access to internal workings.

📖 Black-Box Testing Features

5. Testing Methods (Continued)

5.5 Integration Testing

Software consists of many modules written by different programmers. Integration testing tests that modules work correctly when joined together into one program.

📖 Integration Testing

5.6 Alpha Testing

Alpha testing is performed in-house by software testers before being released to customers. This is the first phase of user acceptance testing.

5.7 Beta Testing

Beta testing is carried out by external users in real-world environments. When software is produced for general sale, there is no specific customer to perform acceptance testing.

📝 Beta Testing Process
  1. After alpha testing, a version is released to limited audience
  2. These beta testers use software in their own environments
  3. The early release version is called beta version
  4. Users feedback any problems to software house
  5. Software house corrects reported faults before final release

5.8 Acceptance Testing

Acceptance testing is the final check to ensure the program meets the original client requirements. For bespoke software, this is performed by the customer.

📖 Acceptance Testing
Testing Method Who Performs It Purpose
Dry Run Programmer Trace through code manually with trace tables
White-box Developer Test internal logic, every path through code
Black-box Tester Test functionality without seeing code
Integration Developer Test modules work together correctly
Alpha In-house testers Early testing before customer release
Beta External users Real-world testing by selected users
Acceptance Customer Final check before sign-off
Stub Developer Test incomplete programs with dummy modules

6. Test Data and Test Plans

6.1 Test Strategy and Test Plan

During the design stage of a software project, a suitable testing strategy must be worked out. We need a test plan to ensure testing of software from the very beginning.

📖 Test Plan Considerations

6.2 Types of Test Data

Type Description Example (Age 12-18)
Normal (Valid) Typical data values that are valid Age = 14, 16
Abnormal (Erroneous) Data values that system should not accept (wrong type) Age = "H", "@", "twenty"
Extreme Maximum and minimum values of normal data accepted Age = 12, 18
Boundary Values on either side of max/min (largest/smallest unacceptable) Age = 11, 19
Example Program: A program accepts user age between 12 and 18 inclusive.
Normal: 14, 16 (accepted) | Extreme: 12, 18 (at boundaries, accepted)
Boundary: 11, 19 (just outside, rejected) | Abnormal: "H", "@" (wrong type, rejected)
11 Boundary 12 Extreme NORMAL DATA 13, 14, 15, 16, 17 18 Extreme 19 Boundary ✗ Rejected ✓ Accepted ✗ Rejected
💡 Exam Tip

Remember: Extreme data is AT the boundary (still valid), while Boundary data is JUST OUTSIDE the boundary (invalid). Both are needed to test the edge cases!

6. Test Data (Continued)

6.3 Sample Test Plan

A program accepts a user's age between 0 and 120 inclusive. Here is a sample test plan:

Test No. Description Input Expected Output Type
1 Valid age within range 25 "Age accepted" Normal
2 Input is not a number "twenty" "Invalid input" Abnormal
3 Age above maximum 130 "Age out of range" Extreme
4 Age at upper boundary 120 "Age accepted" Boundary
5 Age at lower boundary 0 "Age accepted" Boundary
6 Age just below lower boundary -1 "Age out of range" Boundary
7 Blank input (blank) "Please enter your age" Abnormal

6.4 Selecting Suitable Test Data

A program accepts age between 12 and 18 inclusive:

Type Test Input Expected Result
Normal 14 Accepted ✓
Normal 16 Accepted ✓
Extreme 12 Accepted ✓ (minimum valid)
Extreme 18 Accepted ✓ (maximum valid)
Abnormal H Rejected ✗ (wrong type)
Abnormal @ Rejected ✗ (wrong type)
Boundary 11 Rejected ✗ (just below minimum)
Boundary 19 Rejected ✗ (just above maximum)
❌ Common Mistake

Don't confuse extreme data with boundary data! Extreme data is the highest/lowest VALID values (still accepted). Boundary data is just OUTSIDE the valid range (should be rejected). You need to test BOTH!

7. Program Maintenance

Program maintenance is the process of updating or improving a program after it has been delivered to the user. Unlike physical equipment, programs don't wear out, but they may need to be changed due to errors, changing requirements, or new technology.

📖 Why Maintenance is Needed

7.1 Types of Maintenance

Type Purpose Example
Corrective Fixes bugs or errors found during real-world use Fixing a bug that causes crash when special characters entered
Perfective Improves performance or adds small enhancements Replacing loading screen with progress bar for better user feedback
Adaptive Modifies program to support new environments or requirements Modifying program to work on tablets instead of just desktops

7.2 Corrective Maintenance

Corrective maintenance is used to correct any errors that appear during use. For example, trapping a run-time error that had been missed during testing.

📝 Corrective Maintenance Examples

7.3 Perfective Maintenance

Perfective maintenance is used to improve performance of a program during its use. This includes enhancing functionality and improving user experience.

📝 Perfective Maintenance Examples

7.4 Adaptive Maintenance

Adaptive maintenance is used to alter a program so it can perform any new tasks required by the customer or work in new environments.

📝 Adaptive Maintenance Examples

7. Program Maintenance (Continued)

Types of Program Maintenance CORRECTIVE Fix bugs & errors found in use 🐛 Bug fixes 🔧 Error patches PERFECTIVE Improve performance & add enhancements ⚡ Speed optimization ✨ UI improvements ADAPTIVE Adapt to new environments/tasks 📱 New platforms 🔄 New requirements
⚠️ Important Points
🧠 Memory Trick

7.5 The Role of Patches

A patch is a small program released by developers to run with an existing program to correct an error or provide extra functionality. Patches are an essential part of ongoing maintenance.

📖 When Patches Are Used

8. Exam-Style Questions

1. Explain the difference between a syntax error and a logic error. Give an example of each. [4 marks]

Answer:

  • Syntax error: An error in the grammar/rules of the programming language that prevents the program from compiling/running
  • Example: Missing bracket, wrong keyword spelling, missing semicolon
  • Logic error: An error where the program runs but produces incorrect results due to wrong logic
  • Example: Using OR instead of AND, subtracting instead of multiplying, infinite loop

Additional points for deeper understanding:

  • Syntax errors are detected by the compiler/interpreter during compilation
  • Logic errors are only found during testing when comparing expected vs actual output
2. Describe what is meant by a run-time error. Give two examples of run-time errors and explain how they could be prevented. [5 marks]

Answer:

  • A run-time error is an error that occurs during program execution, causing the program to crash or behave unexpectedly
  • Example 1: Division by zero — prevent by checking divisor is not zero before division
  • Example 2: Array index out of bounds — prevent by validating index before accessing array

Additional points for deeper understanding:

  • Other examples: File not found, null pointer reference, type mismatch
  • Exception handling (try-catch) can be used to manage run-time errors gracefully
  • Run-time errors are different from syntax errors (which prevent compilation) and logic errors (which allow execution but wrong results)
3. Compare white-box testing with black-box testing. Include who would perform each type of testing and when it would be used. [6 marks]

Answer:

  • White-box testing: Tests internal logic and code structure; tester knows how the program works
  • Performed by developers who have access to the source code
  • Used to test every path through the code, all branches of IF statements
  • Black-box testing: Tests functionality without seeing internal code; focuses on inputs and outputs
  • Performed by testers who only know the specifications, not the implementation
  • Used to test whether software meets requirements from user's perspective

Additional points for deeper understanding:

  • White-box is also called "glass-box" or "structural testing"
  • Black-box is also called "functional testing" or "specification-based testing"
4. A program requires the user to enter a number between 1 and 100 inclusive. State suitable test data you would use to test this program, identifying the type of test data for each value. [6 marks]

Answer:

  • Normal data: 50, 75 (typical valid values within the range)
  • Extreme data: 1 (minimum valid), 100 (maximum valid)
  • Boundary data: 0 (just below minimum), 101 (just above maximum)
  • Abnormal data: "ABC" (wrong data type), -5 (negative number)

Additional points for deeper understanding:

  • Extreme data tests the edges of valid input range (should be accepted)
  • Boundary data tests just outside the valid range (should be rejected)
  • Testing both boundary and extreme ensures the boundary conditions work correctly
5. Describe the differences between alpha testing and beta testing. [4 marks]

Answer:

  • Alpha testing: Performed in-house by software testers before release to customers
  • Done in a controlled environment by the development company's own staff
  • Beta testing: Performed by external users in real-world environments
  • A limited version is released to selected users (beta testers) who test in their own environments

Additional points for deeper understanding:

  • Alpha testing comes before beta testing in the testing lifecycle
  • Beta testers provide feedback on problems found in real-world usage
  • Beta testing is essential for software released for general sale (no specific customer for acceptance testing)

8. Exam-Style Questions (Continued)

6. Explain what is meant by integration testing and why it is necessary. [4 marks]

Answer:

  • Integration testing tests that different modules or components work correctly together when combined
  • It is necessary because individual modules may pass all tests but still fail when combined
  • Tests the interfaces between modules
  • Usually done incrementally, adding modules one at a time

Additional points for deeper understanding:

  • Different modules may be written by different programmers
  • Data passed between modules may be formatted differently than expected
  • Integration testing catches errors that unit testing cannot find
7. Describe the three types of program maintenance. For each type, give an example. [6 marks]

Answer:

  • Corrective maintenance: Fixes bugs or errors found during real-world use
  • Example: Fixing a bug that causes program to crash when special characters are entered
  • Perfective maintenance: Improves performance or adds enhancements
  • Example: Replacing a loading screen with a progress bar for better user feedback
  • Adaptive maintenance: Modifies program for new environments or requirements
  • Example: Modifying the program to work on tablets instead of just desktop computers

Additional points for deeper understanding:

  • Corrective: Fixing what's broken (bugs)
  • Perfective: Making things better (improvements)
  • Adaptive: Changing for new situations (new platforms)
8. Explain the purpose of stub testing and when it would be used. [4 marks]

Answer:

  • Stub testing uses temporary dummy modules to simulate missing components during early testing
  • Used during development of modular programs, before all modules are fully implemented
  • A stub typically contains an output statement or returns a fixed value
  • Indicates that the call to the module has been made successfully

Additional points for deeper understanding:

  • Allows testing of incomplete programs
  • Helps identify interface problems early in development
  • Enables parallel development where different programmers work on different modules
9. Explain the difference between extreme data and boundary data. Use an example to illustrate your answer. [4 marks]

Answer:

  • Extreme data is at the maximum and minimum values of normal data that are ACCEPTED by the system
  • Boundary data is just OUTSIDE the maximum and minimum values — the largest and smallest unacceptable values
  • Example: For age range 12-18 inclusive:
  • Extreme data: 12 and 18 (at boundaries, should be accepted)
  • Boundary data: 11 and 19 (just outside, should be rejected)

Additional points for deeper understanding:

  • Both types are needed to fully test boundary conditions
  • Extreme tests that the boundary IS included (valid)
  • Boundary tests that values outside ARE rejected (invalid)
10. What is a trace table and how is it used in program testing? [5 marks]

Answer:

  • A trace table is a table used to track the values of variables during program execution
  • Used during dry running (manually stepping through the program on paper)
  • Columns show the values of each variable as they change through each step
  • Helps identify logic errors by comparing expected values with actual values
  • Allows programmers to verify algorithms work correctly before running the program

Additional points for deeper understanding:

  • Trace tables are especially useful for finding logic errors
  • Can be used to test with different input data sets
  • Also called a "walkthrough" when done step-by-step

9. Glossary

Term Definition
Syntax Error An error in the grammar/rules of a programming language that prevents compilation
Logic Error An error where the program runs but produces incorrect results due to wrong logic
Run-time Error An error that occurs during program execution, causing the program to crash
Bug A fault or error in a program
Debugging The process of finding and correcting errors in a program
Patch A small program released to correct an error or add functionality to existing software
Dry Run Manually tracing through code on paper to predict output and track variables
Trace Table A table showing values of variables at each step of program execution
White-box Testing Testing internal logic and code structure with knowledge of how the program works
Black-box Testing Testing functionality without knowledge of internal code, focusing on inputs/outputs
Integration Testing Testing that different modules work correctly when combined together
Alpha Testing In-house testing by software testers before release to customers
Beta Testing Testing by external users in real-world environments
Acceptance Testing Final testing by customer to verify software meets requirements before sign-off
Stub Testing Testing using dummy modules to simulate missing components
Normal Data Typical valid data values that should be accepted by the system
Abnormal Data Data values of wrong type that the system should not accept
Extreme Data Maximum and minimum valid values at the boundaries of accepted range
Boundary Data Values just outside the valid range that should be rejected
Corrective Maintenance Maintenance to fix bugs and errors found during real-world use
Perfective Maintenance Maintenance to improve performance or add enhancements
Adaptive Maintenance Maintenance to adapt software for new environments or requirements

10. Exam Success Tips (Part 1)

💡 Error Types - Key Reminders
💡 Testing Methods - Remember the Order
💡 Test Data - The Four Types
🧠 Memory Trick: Extreme vs Boundary
💡 Maintenance Types - CPA

10. Exam Success Tips (Part 2)

⚠️ White-box vs Black-box - Must Mention
❌ Common Mistakes to Avoid
💡 Answer Structure Tips
🌟 Quick Reference
Topic Key Point
Syntax Error Grammar error, program won't compile, found by compiler
Logic Error Wrong results, program runs, found by testing
Run-time Error Program crashes, use exception handling
White-box Tests internal logic, tester knows code
Black-box Tests functionality, tester doesn't know code
Extreme Data At boundary, VALID, should be accepted
Boundary Data Just outside, INVALID, should be rejected

11. Key Takeaways

📌 Summary Points

Error Types

Testing Methods

Test Data Types

Maintenance Types

⚠️ Final Exam Reminders