Types of Test Data — GDScript
A testing table is only as strong as the range of data it feeds in. Six kinds — and a table that reaches 7–8 visits them all.
The six types
| Type | Meaning | Age-checker example |
|---|---|---|
| Valid | normal values that should work | 20, 25 |
| Valid but unusual | uncommon but acceptable | a 65-year-old student |
| Invalid | breaks the rules | 15, 17 |
| Boundary | at the exact limit | 17, 18, 19 |
| Wrong | wrong format or type | "twenty", -5 |
| Absent | missing entirely | "", null |
Story 1 — the age checker
Students must be 18 or older to enrol:
func check_age(age): if age >= 18: return "Eligible for enrolment" return "Too young - must be 18+"
Fill in an appropriate age for each row, then run them:
| Test ID | Description | Test data type | Input | Expected output | Actual output | Result |
|---|---|---|---|---|---|---|
| TC001 | Valid adult age | Valid | age = | "Eligible for enrolment" | "Eligible for enrolment" | ✅ Pass |
| TC002 | Older student | Valid but unusual | age = | "Eligible for enrolment" | "Eligible for enrolment" | ✅ Pass |
| TC003 | Under-age student | Invalid | age = | "Too young - must be 18+" | "Too young - must be 18+" | ✅ Pass |
| TC004 | Minimum age boundary | Boundary | age = | "Eligible for enrolment" | "Eligible for enrolment" | ✅ Pass |
| TC005 | Just under boundary | Boundary | age = | "Too young - must be 18+" | "Too young - must be 18+" | ✅ Pass |
| TC006 | Text instead of number | Wrong | age = "twenty" | Error message | Game crashes | ❌ Fail |
| TC007 | Missing age | Absent | age = null | Error message | Game crashes | ❌ Fail |
Answer
| Test ID | Suggested age | Reasoning |
|---|---|---|
| TC001 | 20 | normal adult student |
| TC002 | 65 | unusual but perfectly valid |
| TC003 | 13 | clearly under the minimum |
| TC004 | 18 | exactly at the boundary — minimum valid |
| TC005 | 17 | one below the boundary |
The last two rows are the lesson: "twenty" >= 18 is an invalid String-vs-int comparison, so the game crashes instead of returning an error message. Wrong and Absent data are exactly the rows that expose missing validation checks — and every crash they cause belongs in your table as a Fail with a corrective action.
Story 2 — the GPA calculator (practice)
A GPA calculator that validates its inputs and decides graduation eligibility (needs GPA ≥ 2.0 and ≥ 120 credits):
func calculate_gpa(student_id, grades: Array, credits: Array): if not str(student_id).is_valid_int() or str(student_id).length() != 8: return {"error": "Invalid student ID"} if grades.size() != credits.size(): return {"error": "Grades and credits must match"} var total_points := 0.0 var total_credits := 0 for i in grades.size(): if grades[i] < 0 or grades[i] > 100: return {"error": "Grade %s out of range" % grades[i]} var points := 0.0 if grades[i] >= 80: points = 4.0 elif grades[i] >= 70: points = 3.0 elif grades[i] >= 60: points = 2.0 total_points += points * credits[i] total_credits += credits[i] if total_credits == 0: return {"error": "No credits provided"} var gpa := total_points / total_credits if gpa >= 2.0 and total_credits >= 120: return {"status": "graduate", "gpa": snapped(gpa, 0.01)} return {"status": "not ready", "gpa": snapped(gpa, 0.01)}
No answer key for this table. The blank rows are open-ended — you choose the input data. Run your own inputs through the code above and record what actually happens.
| Test ID | Test data type | Input | Expected output | Actual output | Result |
|---|---|---|---|---|---|
| TC001 | Valid | ID=12345678, grades=[85,90], credits=[3,3] | {"status": "graduate", "gpa": 4.0} | {"status": "not ready", "gpa": 4.0} | ❌ Fail |
| TC002 | Valid | ||||
| TC003 | Valid but unusual | ID=87654321, grades=[60,80], credits=[60,60] | {"status": "graduate", "gpa": 3.5} | {"status": "graduate", "gpa": 3.0} | ❌ Fail |
| TC004 | Valid but unusual | ||||
| TC005 | Invalid | ID=11111111, grades=[50,40], credits=[3,3] | {"status": "not ready", "gpa": 0.0} | {"status": "not ready", "gpa": 0.0} | ✅ Pass |
| TC006 | Invalid | ||||
| TC007 | Boundary | ID=22222222, grades=[70,70], credits=[60,60] | {"status": "graduate", "gpa": 2.0} | {"status": "graduate", "gpa": 3.0} | ❌ Fail |
| TC008 | Boundary | ||||
| TC009 | Wrong | ID="ABCD1234", grades=[80], credits=[3] | {"error": "Invalid student ID"} | {"error": "Invalid student ID"} | ✅ Pass |
| TC010 | Wrong | ||||
| TC011 | Absent | ID=55555555, grades=[], credits=[] | {"error": "No credits provided"} | {"error": "No credits provided"} | ✅ Pass |
| TC012 | Absent |
Testing reveals issues on both sides. TC001: only 6 credits, but graduation needs 120+ — the expected output was wrong. TC003: the calculated GPA is 3.0 (60→2.0, 80→4.0, equal credits), not 3.5 — expected output wrong again. TC007: GPA is 3.0, not 2.0 — same.
Key learning: testing exposes errors in your expected outputs (test-design mistakes) as well as in the code. Working out the expected value before you run is what makes a testing table a test, not a transcript.
