Learn
7.6.3 | TEST PLANS, EXPECTED RESULTS AND ACTUAL RESULTS
01 | A TEST NEEDS A QUESTION TO ANSWER
You open a booking program, type an identifier and see a message. “I tried it and it worked” is not enough to show which rule was checked or what evidence supports that conclusion.
A test plan sets out the cases you intend to run and the behaviour you expect. It makes testing purposeful rather than a series of random clicks.
A test record adds what actually happened and whether that behaviour met the requirement. A proposed plan and a completed record are therefore different stages of the work.
This lesson develops a plan from a simple requirement, follows illustrative observations, and shows how a failure leads to debugging and retesting. You do not need a large project to understand the method.
02 | START WITH A CLEAR REQUIREMENT
Our example is a mark-entry form. A required mark must be a whole number from zero to fifty inclusive. Acceptable input is stored against the selected student. Unacceptable input must produce a useful message, must not replace the stored mark and must allow correction.
These statements define success. They tell us to test ordinary acceptance, accepted endpoints, rejected values, type handling, presence and stored-data behaviour.
A vague requirement such as “the form must work” gives no independent standard against which to assess the result.
Each case should connect to a requirement or likely fault. This connection is sometimes called traceability: you can trace the reason for the test back to the behaviour it is meant to check.
If the required response is unclear, clarify it before writing expected outcomes. Do not silently invent a feature such as rounding fractional marks.
03 | WHAT BELONGS IN A TEST CASE?
A useful test case includes a clear identifier, its purpose, the starting conditions, the input or actions and the expected result.
| Part | What it establishes |
|---|---|
| Test ID and purpose | Which case and requirement are being checked |
| Starting state | Records and conditions before execution |
| Input or actions | The precise data and steps to supply |
| Expected result | Required output, state changes and response |
| Actual result and outcome | Observed behaviour and pass/fail after running |
A test identifier such as T01 makes the case easy to reference in a failure report or retest. It does not change the test itself.
Some small calculations do not need elaborate setup. State matters when the behaviour depends on records, capacity, user choices or earlier actions.
Include enough detail for another person to reproduce the case. “Enter a bad mark” is not repeatable in the same way as “enter numeric whole number 500 into the selected student’s mark field”.
04 | EXPECTED RESULTS COME FROM REQUIREMENTS
The expected result is what should happen if the system meets the requirement. Work it out before running the case.
For input 34, expect acceptance and storage of 34 against the selected student. For input 500, expect range rejection, no replacement of a stored valid mark and an opportunity to re-enter.
For input zero, expect acceptance because the range includes its lower endpoint. A programmer’s current code might reject it, but that would not change the requirement.
Do not let the program define its own success. If you write down whatever it does and then call that the expected result, an incorrect implementation can appear to pass every test.
An expectation should be specific enough to compare with observations. “A good message appears” is vague; “a range error is shown and the user can enter a replacement” is testable.
05 | BUILD A SMALL PLAN WITH USEFUL COVERAGE
The table below is a proposed plan for the full mark form. Before each independent case, select student S104 and set their existing stored mark to 20. This makes the expected storage changes explicit.
| ID | Input | Role | Expected result | Actual result |
|---|---|---|---|---|
| T01 | 34 | Normal | Accept; store 34 for S104 | Not run |
| T02 | 0 | Lower extreme / boundary | Accept; store 0 for S104 | Not run |
| T03 | 50 | Upper extreme / boundary | Accept; store 50 for S104 | Not run |
| T04 | -1 | Rejected boundary neighbour | Reject; mark stays 20; allow retry | Not run |
| T05 | 51 | Rejected boundary neighbour | Reject; mark stays 20; allow retry | Not run |
| T06 | 12.5 | Abnormal type | Reject; mark stays 20; allow retry | Not run |
| T07 | hello | Abnormal type | Controlled rejection; no crash; mark stays 20 | Not run |
| T08 | Empty | Abnormal presence | Required-field message; mark stays 20 | Not run |
Normal, abnormal, extreme and boundary labels can overlap, as explained in the previous lesson. Accepted endpoints are extreme and part of the boundary set; nearby rejected values are abnormal boundary neighbours.
For text or fractional input, test the actual input routine. A small pseudocode fragment that assumes numeric whole-number input does not automatically implement those cases.
The plan’s actual-result column is not filled yet because the tests have not been run.
06 | ACTUAL RESULTS ARE OBSERVATIONS
The actual result is what you observe when the implementation runs. Record it accurately, including unexpected behaviour.
If input zero produces “Outside range”, record that message. Do not copy “Accept zero” from the expected column simply because that was what you hoped would happen.
Inspect the stored record as well as the screen. A success message can appear while the wrong record is updated. A rejection message can appear while an invalid value is still saved.
If you did not inspect storage, do not claim that it remained unchanged. Record what was observed and what still needs checking.
Test evidence can include a screenshot, a displayed value, a relevant log or inspection of a record. Choose evidence that supports the particular conclusion, rather than collecting screenshots with no stated purpose.
07 | COMPARE EXPECTED AND ACTUAL BEHAVIOUR
A test passes when the actual behaviour meets the expected requirement. It fails when required behaviour is missing or incorrect.
| Case | Expected | Illustrative actual result | Outcome |
|---|---|---|---|
| T01: 34 | Accept and store 34 | Accepted; S104 stores 34 | Pass |
| T02: 0 | Accept and store 0 | Range error; S104 stays 20 | Fail |
| T05: 51 | Reject; unchanged; retry | Range error; stays 20; retry available | Pass |
| T07: hello | Controlled rejection; no crash | Unhandled conversion error | Fail |
These actual outcomes are illustrative, not observations from a deployed mark form. They show how a record should distinguish expectation from result.
The abnormal case passes because the required action is rejection. The zero case fails because zero should be accepted. The text case fails because an unhandled error is not the required controlled response.
If no run has taken place, use a status such as “Not run”. If evidence is incomplete, mark the case unresolved or incomplete rather than claiming a full pass.
08 | DO NOT STOP AT THE FIRST VISIBLE MESSAGE
Suppose the form rejects 51 and displays the correct range message. That checks one output. The requirement also says not to replace the stored mark and to allow correction.
Inspect S104’s stored mark: it should still be 20 in this case’s starting setup. Then enter 34 and confirm it can be accepted and stored.
You can design a sequence specifically for retry behaviour: start with mark 20, input 51, observe rejection and unchanged storage, then input 34 and observe successful correction.
This is not the same as an independent single-input case. Record the actions and expected state after each step so another tester can repeat it.
If a case has several required outcomes and one fails, it has not fully passed. Split a very large case into smaller ones when doing so improves clarity.
09 | STARTING CONDITIONS MAKE RESULTS REPEATABLE
A booking test depends on the stored collection. With capacity three and identifiers S104 and S205 already booked, new S306 should be accepted.
After that acceptance, the club is full. Testing another identifier without resetting now exercises a different starting state.
| Starting accepted IDs; capacity 3 | Input | Expected |
|---|---|---|
| S104, S205 | S306 | Accept; records become S104, S205, S306 |
| S104, S205 | S104 | Reject duplicate; records unchanged |
| S104, S205, S306 | S407 | Reject full; records unchanged |
For independent cases, reset to the specified records before each run. For a deliberate sequence, retain the changes and describe them.
Record any environment detail that affects interpretation, such as the tested code version or data set. A record saying “passed” is less useful if nobody knows which implementation produced the result.
Repeatability means reconstructing the stated conditions, not merely pressing the same button twice on different data.
10 | A FAILED TEST GUIDES DEBUGGING
Suppose T02, the zero-mark case, fails. The current condition is Mark > 0 AND Mark <= 50. It excludes zero even though the requirement includes it.
// Fault: excludes an accepted lower endpoint Accepted ← Mark > 0 AND Mark <= 50 // Correction to match the inclusive requirement Accepted ← Mark >= 0 AND Mark <= 50
Testing revealed the disagreement. Debugging locates its cause and corrects it. Changing the lower comparison to >= addresses this specific cause.
Do not change the expected result to “Reject zero” just to make the record pass. That would hide a failure unless the actual requirement had formally changed.
A test record helps the developer reproduce the fault: it states the input, setup, expected outcome and observed outcome rather than only saying “there is a bug”.
11 | RETEST THE FIX AND CHECK PREVIOUSLY WORKING CASES
After correcting the comparison, rerun T02 from its stated starting conditions. The new observation should show whether zero is accepted and stored correctly.
Also rerun relevant cases that previously worked: ordinary 34, upper endpoint 50 and rejected values such as 51. A change can fix one behaviour while accidentally affecting another.
Checking previously working behaviour after a change is called regression testing. It complements retesting the original failure.
| Case | Version | Illustrative observed result | Conclusion |
|---|---|---|---|
| T02: 0 | A, before fix | Rejected incorrectly | Fail retained in record |
| T02: 0 | B, after fix | Accepted; S104 stores 0 | Retest passes |
| T01: 34 | B | Accepted; S104 stores 34 | Regression case passes |
| T05: 51 | B | Rejected; unchanged; retry available | Regression case passes |
Keep the earlier failing result as evidence and add the later run. Do not rewrite history so that the problem appears never to have existed.
A corrected condition is a proposed fix. A successful retest supplies evidence that the failing case is now handled as required.
12 | MAKE COVERAGE MEANINGFUL
Ten ordinary accepted marks do not necessarily provide better coverage than a carefully selected mixture of normal, abnormal, extreme and boundary cases.
Consider the conditions and paths in the implementation. Does the plan check ordinary acceptance, each required rejection reason, storage updates, record association and correction after rejection?
For a calculation, choose inputs that distinguish likely mistakes. Values 4, 7 and 2 separate a total of 13 from a count of 3, whereas three ones make both results equal.
Coverage is the set of requirements, situations and paths exercised. It is not simply the number of rows.
Passing a finite plan does not prove all possible behaviours. State what was tested and identify important omissions rather than claiming the entire program is guaranteed correct.
13 | WRITE CLEAR TEST RECORDS
Use short, concrete descriptions. “Input 51; range message shown; stored mark remains 20; replacement accepted” provides more evidence than “works”.
Keep expected and actual columns separate. Use a clear result status, identify the tested version and add a brief fault or retest note when useful.
Exact wording is only essential when the requirement specifies it. Otherwise describe the required meaning and action rather than failing a correct message because of harmless punctuation.
Do not label a case “Pass” if you observed only part of its expected behaviour. Record the incomplete check and finish it before concluding.
The aim is a useful communication record: another person should understand what was checked, what happened and what remains unresolved.
14 | EXPLAIN THE PROCESS WITH REASONS
For a describe question, state that the plan identifies cases and expected outcomes, the tester runs them under stated conditions and records actual outcomes.
For an explain question, connect expectation to judgement: “Expected results are derived from requirements before execution, so they provide an independent standard against which the actual behaviour can be assessed.”
A clear retesting explanation is: “After fixing the fault, rerun the failing case to check the correction and relevant previously passed cases to detect unintended effects.”
You should now be able to construct a repeatable plan, record observations honestly and use failures as evidence for improvement. The next lesson traces algorithms by hand, recording variables, outputs and prompts.