1.3 Tracing, Testing, and Improving Algorithms
Compare required and observed behavior, repair defects, and retest
A specification states what an algorithm must do. For a chosen input, first determine the required result. Then follow the algorithm and compare the result it produces. Carefully chosen inputs can reveal incorrect decisions, state changes, and repetition that does not stop.
1.3.1 Why algorithms need to be tested
The bottle-filling exercise from Chapter 1.2 requires a bottle to finish exactly full. Consider a proposed algorithm that pours one full cup whenever the bottle is not yet full. Calculate its final bottle volume for each case in Table 1.
| Bottle capacity | Cup capacity | Bottle volume after each pour | Required final volume | Observed final volume | Verdict |
|---|---|---|---|---|---|
| 800 mL | 200 mL | 200, 400, 600, 800 |
800 mL | 800 mL | Pass |
| 750 mL | 200 mL | 200, 400, 600, 800 |
750 mL | 800 mL | Fail |
The 800 mL case passes because four full cups fit exactly. The 750 mL case exposes an overflow on the final pour. Both cases follow the same instructions, so the choice of input determines whether the defect becomes visible.
For one chosen input, the expected result comes from the specification. The observed result comes from following the algorithm. A verdict is Pass when the two results agree and Fail when they differ. One passing test supports the algorithm for that input. It does not establish correct behavior for every permitted input (International Software Testing Qualifications Board 2024).
1.3.2 Tracing decisions and changing state
Chapter 1.2’s even-or-odd algorithm in Listing 1 has one condition and two paths. Its decision table in Table 1 states the required result for each rule. Table 2 uses ordinary and unusual integers to follow both paths.
| Test | Input | Purpose | Expected result | Observed result | Verdict |
|---|---|---|---|---|---|
| E1 | 8 | Ordinary even integer | Even | Even | Pass |
| E2 | 7 | Ordinary odd integer | Odd | Odd | Pass |
| E3 | 0 | Unusual permitted even integer | Even | Even | Pass |
| E4 | -3 | Negative odd integer | Odd | Odd | Pass |
A trace is a step-by-step record of one execution. In E1 and E3, dividing by 2 leaves no remainder, so the algorithm follows the Even path. In E2 and E4, it leaves a remainder, so the algorithm follows the Odd path. These traces are short because the algorithm evaluates only one condition. A test adds the required result and a verdict. Longer algorithms need a separate row for each relevant instruction or iteration. External trace records reduce the amount of changing information that a learner must hold in memory (Xie et al. 2018).
The completed algorithm from the bottle-filling exercise limits each pour to the space that remains. State is information that may change while an algorithm runs. The changing state here is Bottle Volume and Cupfuls. Table 3 records both values after every round.
| Round | Bottle Volume before |
Space remaining before | Amount poured | Bottle Volume after |
Cupfuls after |
|---|---|---|---|---|---|
| 1 | 0 mL | 750 mL | 200 mL | 200 mL | 1 |
| 2 | 200 mL | 550 mL | 200 mL | 400 mL | 2 |
| 3 | 400 mL | 350 mL | 200 mL | 600 mL | 3 |
| 4 | 600 mL | 150 mL | 150 mL | 750 mL | 4 |
The space remaining decreases from 750 mL to 0 mL. The final cup contains 50 mL after the algorithm pours the 150 mL still needed. Recording values before and after each round makes every state change visible.
1.3.3 Choosing effective test cases
Each test case should have a reason. A decision table suggests at least one input for each rule. An ordered threshold suggests inputs immediately below, at, and above the threshold. Repetition suggests cases with zero, one, and several iterations.
A test case records its purpose, input or starting conditions, procedure, and expected result. A test plan collects the cases before the algorithm is followed. Writing expectations first prevents the algorithm’s output from defining its own correctness. Students without explicit testing instruction often derive cases from code and omit known expected results (Bijlsma et al. 2021).
A campus minibus has a fixed number of seats. Groups submit booking requests in arrival order, and each group must remain together. Accept a request when the entire group fits. Reject it otherwise, then consider the next request.
The specification contains these rules:
Seat Capacityis a positive whole number.Group Requestsis a finite, ordered collection of positive whole numbers. For example,[4, 7, 3]means requests for 4, 7, and 3 seats in that order.[]is an empty collection.Booked Seatsstarts at 0. Accept a request whenBooked Seats + Seats Requested <= Seat Capacity. The symbol<=means “less than or equal to.” A rejected request leavesBooked Seatsunchanged.- Process every request once in its original order. Produce one decision for each request and the final number of booked seats.
- An empty collection produces no decisions and a final value of 0 booked seats.
All examples below use inputs that satisfy the first rule. For Seat Capacity = 10 and Group Requests = [4, 6], the required decisions are Accept, Accept, and the expected final value is 10.
With 4 seats already booked, requests for 5, 6, and 7 seats produce totals of 9, 10, and 11. Totals 9 and 10 fit, while 11 does not. The total of 10 is the decision threshold. Values immediately below, at, and above a threshold can expose an incorrect comparison. Selecting these cases is called boundary-value analysis (International Software Testing Qualifications Board 2024). The empty collection checks the result when repetition performs zero iterations.
Table 4 records the expected results before the proposed algorithm is inspected.
| ID | Purpose | Input | Expected decisions | Expected final booked seats |
|---|---|---|---|---|
| T1 | Ordinary sequence with mixed decisions | Seat Capacity = 10, Group Requests = [4, 7, 3] |
Accept, Reject, Accept |
7 |
| T2 | Finish 1 seat below capacity | Seat Capacity = 10, Group Requests = [4, 5] |
Accept, Accept |
9 |
| T3 | Fill the minibus exactly | Seat Capacity = 10, Group Requests = [4, 6] |
Accept, Accept |
10 |
| T4 | Exceed capacity by 1 seat | Seat Capacity = 10, Group Requests = [4, 7] |
Accept, Reject |
4 |
| T5 | Process zero requests | Seat Capacity = 10, Group Requests = [] |
No decisions | 0 |
T2, T3, and T4 vary only the second request. The three cases test totals of 9, 10, and 11 around the capacity threshold. T5 checks the stated result when there are no requests.
1.3.4 Finding defects through tracing
Listing 1 uses < in its booking condition. The notation For each Seats Requested in Group Requests selects each request in its original order. It advances automatically and stops after the last item. End For marks the end of the repeated instructions.
Input: Seat Capacity, Group Requests
Output: Decisions and Final Booked Seats
Start
Set Booked Seats to 0
Set Decisions to an empty collection
For each Seats Requested in Group Requests
If Booked Seats + Seats Requested < Seat Capacity
Set Decision to "Accept"
Set Booked Seats to Booked Seats + Seats Requested
Else
Set Decision to "Reject"
End If
Add Decision to Decisions
End For
Output Decisions, Booked Seats
EndTrace T1 one request at a time. In Table 5, record the state before the condition, the condition’s result, the selected decision, and the state afterward.
| Step | Seats requested | Booked Seats before |
Evaluated condition | Decision | Booked Seats after |
|---|---|---|---|---|---|
| 1 | 4 | 0 | 0 + 4 < 10 is true |
Accept | 4 |
| 2 | 7 | 4 | 4 + 7 < 10 is false |
Reject | 4 |
| 3 | 3 | 4 | 4 + 3 < 10 is true |
Accept | 7 |
The rejected request remains visible in Table 5. A blank cell would not show whether the value stayed at 4 or was omitted.
T3 tests the exact-fit threshold. Table 6 shows the first point where the proposed algorithm and the specification require different decisions.
| Seats requested | Booked Seats before |
Evaluated condition | Observed decision | Required decision | Booked Seats after |
|---|---|---|---|---|---|
| 4 | 0 | 0 + 4 < 10 is true |
Accept | Accept | 4 |
| 6 | 4 | 4 + 6 < 10 is false |
Reject | Accept | 4 |
Add each observed result and verdict to the test record in Table 7 after tracing.
| Test | Expected result | Observed result | Verdict |
|---|---|---|---|
| T1 | Accept, Reject, Accept; final booked seats 7 |
Accept, Reject, Accept; final booked seats 7 |
Pass |
| T2 | Accept, Accept; final booked seats 9 |
Accept, Accept; final booked seats 9 |
Pass |
| T3 | Accept, Accept; final booked seats 10 |
Accept, Reject; final booked seats 4 |
Fail |
| T4 | Accept, Reject; final booked seats 4 |
Accept, Reject; final booked seats 4 |
Pass |
| T5 | No decisions; final booked seats 0 |
No decisions; final booked seats 0 |
Pass |
A defect is an error that makes an algorithm violate its specification for at least one permitted input. The first mismatch in T3 occurs on the second request. The specification requires acceptance because 4 + 6 <= 10 is true. The proposal tests 4 + 6 < 10, which is false.
1.3.5 Repairing and retesting
A repair changes the instruction that caused the mismatch. A retest repeats the failed case and related cases after the change. Replace < with <= so that the booking condition includes an exact fit. Listing 2 shows the corrected selection.
Retest the failed exact-fit case first. Then repeat the nearest cases below and above the threshold because the changed comparison can affect them. Record the 3 results in Table 8.
| Test | Purpose | Expected result | Observed result after repair | Verdict |
|---|---|---|---|---|
| T3 | Fill the minibus exactly | Accept, Accept; final booked seats 10 |
Accept, Accept; final booked seats 10 |
Pass |
| T2 | Finish 1 seat below capacity | Accept, Accept; final booked seats 9 |
Accept, Accept; final booked seats 9 |
Pass |
| T4 | Exceed capacity by 1 seat | Accept, Reject; final booked seats 4 |
Accept, Reject; final booked seats 4 |
Pass |
The retests provide evidence for these three inputs. Other permitted request collections require their own evidence.
1.3.6 Checking termination
Termination means that an algorithm eventually stops for every permitted input. The For each repetition in Listing 1 advances through a finite collection automatically. A While repetition checks its condition before every iteration. Its instructions must change the loop-control state until the condition becomes false.
Listing 3 makes request advancement explicit. Remaining Requests is a working copy of Group Requests. Reading its first item selects the next request. Removing that item shortens the working copy. The proposal removes a request only after acceptance.
Input: Seat Capacity, Group Requests
Output: One decision for each request and Final Booked Seats
Start
Set Booked Seats to 0
Set Remaining Requests to a copy of Group Requests
While Remaining Requests is not empty
Set Seats Requested to the first request in Remaining Requests
If Booked Seats + Seats Requested <= Seat Capacity
Set Booked Seats to Booked Seats + Seats Requested
Output "Accept"
Remove the first request from Remaining Requests
Else
Output "Reject"
End If
End While
Output Booked Seats
EndThe loop-control state is the value used to decide whether repetition continues. Here the condition depends on Remaining Requests. Trace Seat Capacity = 10 and Group Requests = [4, 7] until that state repeats. Table 9 records the first repeated state.
| Iteration | Booked Seats before to after |
Remaining Requests before to after |
Seats requested | Decision |
|---|---|---|---|---|
| 1 | 0 to 4 |
[4, 7] to [7] |
4 | Accept |
| 2 | 4 to 4 |
[7] to [7] |
7 | Reject |
After iteration 2, Remaining Requests is not empty stays true and the same request remains first. Every later iteration repeats the same rejection.
Move the removal instruction after the selection so that every decision advances to the next request. Listing 4 shows the repaired position of that instruction.
Retest an empty collection, one accepted request, and a sequence containing a rejection. Use Table 10 to compare how each input changes Remaining Requests.
| Input | Decisions | Final booked seats | Change in Remaining Requests |
Stops? |
|---|---|---|---|---|
Seat Capacity = 10, Group Requests = [] |
No decisions | 0 | Already empty | Yes |
Seat Capacity = 10, Group Requests = [4] |
Accept |
4 | [4] to [] |
Yes |
Seat Capacity = 10, Group Requests = [4, 7] |
Accept, Reject |
4 | [4, 7] to [7] to [] |
Yes |
The number of remaining requests decreases by 1 on every iteration. A finite collection therefore becomes empty and makes the loop condition false.
The same stopping questions apply to the repetition introduced in Chapter 1.2. Table 11 compares the state and progress argument for each repetition.
| Algorithm | Repetition condition | Loop-control state | Progress toward stopping |
|---|---|---|---|
| Fill the bottle | Bottle Volume < Bottle Capacity |
Bottle Volume |
The remaining capacity decreases to 0. |
| Correct a PB&J spread | The spread is uneven | The condition of the spread | The specification assumes that each correction improves the spread until it is even. |
| Process minibus requests | Remaining Requests is not empty |
Remaining Requests |
The number of remaining requests decreases by 1. |
The repaired minibus While repetition implements definite iteration because the starting collection has a known finite size and every iteration removes one request. The PB&J spread uses condition-controlled repetition because the number of corrections is not known in advance. The control rule determines the type of iteration.
1.3.7 A reusable checking sequence
Use the sequence in Table 12 to produce the same records for other short algorithms.
| Activity | Question | Record |
|---|---|---|
| State required behavior | What must the algorithm do? | Relevant specification rules |
| Plan a test case | Which input is being checked, and what result is required? | Test plan with purpose, input, and expected result |
| Trace and compare | What result does the algorithm produce, and does it match? | Trace table, observed result, and verdict |
| Repair and retest | Which instruction causes the first mismatch, and does the repair preserve related behavior? | Repaired instructions and retest results |
| Check termination | Why does the repetition eventually stop? | Stopping trace and termination explanation |
1.3.8 Exercises
Complete the first three exercises in order. The first supplies part of the trace. The second supplies the decision threshold and requires you to plan, trace, repair, and retest. The third requires you to diagnose a stopping defect and justify why the repair stops. The optional exercise applies the complete checking sequence to the umbrella decision tables from Chapter 1.2.
1.3.Q1 Trace minibus seat bookings
Scenario. A campus minibus has 12 seats. Groups request 5, 9, and 7 seats in that order. A request is accepted only when the whole group fits in the seats that remain.
Inputs. Seat Capacity = 12 and Group Requests = [5, 9, 7]. All values are positive whole numbers.
Rules and notation. Booked Seats is the number of seats already assigned. Accepted Group Count is the number of accepted requests. A rejected request does not change either value.
Assumptions. A group cannot be split or moved ahead of another group. A rejected request receives no seats.
Before tracing, state the expected decisions, final booked seats, and accepted group count from the scenario. Then trace Listing 5 one request at a time and record both state values after every decision.
Input: Seat Capacity, Group Requests
Output: Decisions, Final Booked Seats, Accepted Group Count
Start
Set Booked Seats to 0
Set Accepted Group Count to 0
Set Decisions to an empty collection
For each Seats Requested in Group Requests
If Booked Seats + Seats Requested <= Seat Capacity
Set Booked Seats to Booked Seats + Seats Requested
Set Accepted Group Count to Accepted Group Count + 1
Set Decision to "Accept"
Else
Set Decision to "Reject"
End If
Add Decision to Decisions
End For
Output Decisions, Booked Seats, Accepted Group Count
EndTable 13 supplies the first row. Complete the remaining rows before opening the solution.
| Step | Seats requested | Booked before | Count before | Evaluated condition | Decision | Booked after | Count after |
|---|---|---|---|---|---|---|---|
| 1 | 5 | 0 | 0 | 0 + 5 <= 12 is true |
Accept | 5 | 1 |
| 2 | 9 | 5 | 1 | ||||
| 3 | 7 |
Deliverable. State the expected outputs before tracing, complete the trace table, record the observed outputs, and give a verdict.
Success criteria. The trace follows the supplied order, preserves both state values after rejection, never shows more than 12 booked seats, and compares the expected and observed results.
For the second request, evaluate 5 + 9 <= 12. A rejected request does not replace the current number of booked seats.
Table 14 completes the trace and preserves both state values after the rejected request.
| Step | Seats requested | Booked before | Count before | Evaluated condition | Decision | Booked after | Count after |
|---|---|---|---|---|---|---|---|
| 1 | 5 | 0 | 0 | 0 + 5 <= 12 is true |
Accept | 5 | 1 |
| 2 | 9 | 5 | 1 | 5 + 9 <= 12 is false |
Reject | 5 | 1 |
| 3 | 7 | 5 | 1 | 5 + 7 <= 12 is true |
Accept | 12 | 2 |
The decisions are Accept, Reject, Accept. Final Booked Seats is 12, and Accepted Group Count is 2. The rejection in step 2 leaves both state values unchanged. The observed result matches the expected result, so the verdict is Pass.
1.3.Q2 Repair an inclusive parking threshold
Scenario. A parking area is free for stays of 30 minutes or less. Longer stays cost 5 euros.
Inputs. Minutes Parked, a whole number from 0 through 480.
Rules and notation. Output a fee of 0 euros for 30 minutes or less and 5 euros for more than 30 minutes.
Assumptions. The input has already been checked against the stated range. No other rates or fees apply.
Deliverable. Complete the checking sequence in three phases:
- Plan. Record a purpose and expected fee for 29, 30, and 31 minutes before inspecting Listing 6.
- Trace and diagnose. Record the observed fee and verdict for each case. Identify the first mismatch and the condition that causes it.
- Repair and retest. Change only the faulty condition and repeat all three planned tests.
Success criteria. The plan contains values immediately below, at, and above the threshold. The exact-threshold test exposes the defect, the repair follows the “30 minutes or less” rule, and the neighboring cases retain their required results.
Minutes Parked < 30 to choose between a zero-euro and 5-euro fee.
Translate the words “30 minutes or less” into one comparison.
Table 15 compares the first results with the retest results.
| Input | Purpose | Expected fee | Fee with < 30 |
Initial verdict | Fee with <= 30 |
Retest verdict |
|---|---|---|---|---|---|---|
| 29 | Immediately below the threshold | 0 | 0 | Pass | 0 | Pass |
| 30 | Exactly at the threshold | 0 | 5 | Fail | 0 | Pass |
| 31 | Immediately above the threshold | 5 | 5 | Pass | 5 | Pass |
The repaired condition is shown in Listing 7.
The first mismatch occurs at 30 minutes. The expected fee is 0 euros, while the proposed algorithm produces 5 euros because < 30 excludes equality. Repeating 29 and 31 checks that the repair preserves the required behavior on both sides of the decision threshold.
1.3.Q3 Repair a shelf-label stopping defect
Scenario. A library prints one number for every shelf in a row, starting at 1.
Inputs. Number of Shelves, a non-negative whole number. For the main trace, use Number of Shelves = 3.
Rules and notation. The algorithm must output each label number from 1 through Number of Shelves once. An input of 0 produces no labels.
Before tracing, state the required output for 3 shelves: 1, 2, 3. Then trace the first 3 iterations of Listing 8 and inspect how the loop-control state changes.
Label Number after every output while the label number remains at or below the number of shelves.
Assumptions. Printing succeeds and does not change Number of Shelves.
Deliverable. Complete the checking sequence:
- State the expected output and trace the first 3 iterations for 3 shelves.
- Identify the loop-control state and explain how its update moves the state away from stopping.
- Repair only the faulty update. Retest 0, 1, and 3 shelves as zero-iteration, one-iteration, and multi-iteration cases.
- State a progress measure and explain why it reaches zero after the repair.
Success criteria. The trace identifies the update direction, the repair moves the loop-control state toward making the condition false, and each retest prints exactly the required labels before stopping. The termination explanation uses a quantity that decreases by 1 after each printed label.
The loop condition becomes false only when Label Number becomes greater than Number of Shelves.
Table 16 records the first 3 iterations.
Label Number from 1 to 0 to -1 to -2, so the loop condition stays true while the outputs move away from the required labels.
| Iteration | Label number before | Loop condition | Output | Label number after |
|---|---|---|---|---|
| 1 | 1 | 1 <= 3 is true |
1 | 0 |
| 2 | 0 | 0 <= 3 is true |
0 | -1 |
| 3 | -1 | -1 <= 3 is true |
-1 | -2 |
The update moves Label Number in the wrong direction. Replace subtraction with addition, as shown in Listing 9.
Label Number after every output and stops after producing each required label once.
Table 17 records the 3 retests.
| Number of shelves | Labels produced | Final label number |
|---|---|---|
| 0 | No labels | 1 |
| 1 | 1 | 2 |
| 3 | 1, 2, 3 | 4 |
Every repetition increases Label Number by 1. The value eventually becomes Number of Shelves + 1, which makes the loop condition false.
While the condition is true, Number of Shelves - Label Number + 1 is the number of labels still to print. The quantity decreases by 1 after each iteration and reaches 0. The bottle trace in Table 3 uses the same kind of numerical progress. The spread loop in Listing 4 instead relies on the stated assumption that each correction improves the spread until it is even.
1.3.Q4 Optional extension: Test an algorithm from a decision table
Chapter 1.2 gives a complete umbrella table in Table 2 and an equivalent minimized table in Table 3. Use both tables as the specification for testing a proposed algorithm.
Scenario. Take an umbrella only when rain is forecast and the journey includes time outdoors. Leave the umbrella behind in every other case.
Inputs. Rain Forecast and Journey Includes Time Outdoors. Each input is Yes or No.
Rules and notation. The required result is Take an umbrella only for (Yes, Yes). The result is Leave the umbrella behind for the other three input pairs. Any in minimized Rule 3 means that either permitted outdoor value matches.
Assumptions. Both inputs contain a permitted value. Each input pair must produce exactly one result.
Deliverable. Complete the following checking sequence:
- Construct test cases U1 to U4 from the four possible input pairs. Record each case’s purpose, expected result, and matching rule in the minimized table before inspecting the proposed algorithm.
- Trace Listing 10 for every case. Record the observed result and verdict.
- Identify the first mismatch and the condition that causes it. Repair only that condition.
- Retest all four cases. Explain why minimized Rule 3 requires two concrete test cases.
Success criteria. The plan covers all four input pairs. Every input matches one rule in each decision table. The initial tests expose the missing outdoor condition, and all four retests pass after the repair.
Use the proposed algorithm only after recording the expected results.
Use (Yes, Yes), (Yes, No), (No, Yes), and (No, No). Compare the proposed algorithm with the required result for (Yes, No).
Table 18 records the plan and the initial results.
| ID | Input pair | Purpose | Minimized rule | Expected result | Observed result | Verdict |
|---|---|---|---|---|---|---|
| U1 | (Yes, Yes) |
Both requirements hold | Rule 1 | Take an umbrella | Take an umbrella | Pass |
| U2 | (Yes, No) |
Rain without outdoor travel | Rule 2 | Leave the umbrella behind | Take an umbrella | Fail |
| U3 | (No, Yes) |
Outdoor travel without rain | Rule 3 | Leave the umbrella behind | Leave the umbrella behind | Pass |
| U4 | (No, No) |
Neither requirement holds | Rule 3 | Leave the umbrella behind | Leave the umbrella behind | Pass |
U2 is the first mismatch. Its expected result is Leave the umbrella behind, while the proposed algorithm produces Take an umbrella. The condition checks rain but omits Journey Includes Time Outdoors.
Listing 11 adds the missing outdoor condition.
Table 19 records the results after the repair.
| ID | Expected result | Observed result after repair | Verdict |
|---|---|---|---|
| U1 | Take an umbrella | Take an umbrella | Pass |
| U2 | Leave the umbrella behind | Leave the umbrella behind | Pass |
| U3 | Leave the umbrella behind | Leave the umbrella behind | Pass |
| U4 | Leave the umbrella behind | Leave the umbrella behind | Pass |
Minimized Rule 3 uses Any for outdoor travel. It represents both U3 (No, Yes) and U4 (No, No), so both concrete inputs belong in the test plan. The complete and minimized tables require the same result for all four cases.
Before you continue. Check that you can state an expected result before tracing, record changed and unchanged state, choose ordinary and threshold cases from a specification, compare expected and observed results, repair a defect, retest related cases, and explain why repetition stops.