Test data is the set of inputs you choose to check that a program works. A good set covers three types: normal, boundary and invalid. For each input you also write the expected result from the requirement, before the program is run.
This lesson follows validation versus verification and belongs to the validation, verification and testing module.
How do I build a test table?
Take the requirement: “Accept a whole-number age from 13 to 17 inclusive; reject everything else.”
| Type | Meaning | Test values | Expected result |
|---|---|---|---|
| Normal | Typical, allowed | 15 | Accepted |
| Boundary (accepted) | Exactly on a limit | 13, 17 | Accepted |
| Boundary (rejected) | Just outside a limit | 12, 18 | Rejected |
| Invalid | Wrong type or far outside | “abc”, -5, 200 | Rejected |
Why choose 12 and 18 as well as 13 and 17? Because a boundary mistake is a mistake about which side of the limit a value lands on. You only see it by testing both sides.
Worked example
A programmer writes this check. It should accept ages 13 to 17 inclusive.
INPUT Age
IF Age > 13 AND Age < 17 THEN
OUTPUT "Accepted"
ELSE
OUTPUT "Rejected"
ENDIF
Step 1, run the normal value. Age = 15: 15 > 13 is TRUE and 15 < 17 is TRUE, so the output is “Accepted”. Expected: Accepted. Pass.
Step 2, run the accepted boundaries.
| Age | Age > 13 | Age < 17 | Output | Expected | Result |
|---|---|---|---|---|---|
| 13 | FALSE | TRUE | Rejected | Accepted | Fail |
| 17 | TRUE | FALSE | Rejected | Accepted | Fail |
Step 3, run the rejected boundaries. Age = 12: 12 > 13 is FALSE, so “Rejected”. Age = 18: 18 < 17 is FALSE, so “Rejected”. Both match the expected result, so pass.
Step 4, diagnose. The normal value passed, which hid the fault. Only the boundary tests 13 and 17 failed. The fault is that > and < should be >= and <=.
Corrected line:
IF Age >= 13 AND Age <= 17 THEN
Re-running 13 and 17 now gives “Accepted”, as expected.
The mistake to watch for
Mistaken test table: Normal 14, 15, 16. Expected: all accepted.
The student chose three values from the middle, so no value could expose a boundary fault.
Three normal values add almost nothing. Replace two of them with 13, 17, 12 and 18, and add one invalid value such as text. Each row should have a different purpose.
Check yourself
1. A rule says: “Quantity must be 1 to 10 inclusive.” Give the two accepted boundary values and the two rejected values just outside.
Show answer
Accepted boundaries: 1 and 10. Rejected just outside: 0 and 11.
2. For the same rule, give one normal value and one invalid value, each with its expected result.
Show answer
Normal: 5, expected accepted. Invalid: “five” (text), expected rejected. A value such as 500 is also valid test data for rejection.
3. The code is IF Quantity > 1 AND Quantity <= 10 THEN OUTPUT "OK". Which test value exposes the fault and what does the program do?
Show answer
1. The expected result is accepted. But 1 > 1 is FALSE, so the program does not output “OK”. The first comparison should be >=.
Where does this lead next?
Next, practise explaining an expected result before running code, the habit that makes a test table meaningful. Later you will find the branches no test has reached. The safe Python reasoning sandbox lets you run a check like this against a table, and the mixed practice set tests everything together.
If you want someone to review your test tables with you, that is part of online one-to-one Computer Science tuition.