Blame
|
1 | <!-- Generated from applied-computing-au vic/unit3-4/sat/C08-2026/C08-Reference-Godot by port-reference-godot-to-wiki.py — do not hand-edit; re-run the port. --> |
||||||
| 2 | # Types of Test Data — GDScript |
|||||||
| 3 | ||||||||
| 4 | *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.* |
|||||||
| 5 | ||||||||
| 6 | ## The six types |
|||||||
| 7 | ||||||||
| 8 | | Type | Meaning | Age-checker example | |
|||||||
| 9 | |---|---|---| |
|||||||
| 10 | | **Valid** | normal values that should work | 20, 25 | |
|||||||
| 11 | | **Valid but unusual** | uncommon but acceptable | a 65-year-old student | |
|||||||
| 12 | | **Invalid** | breaks the rules | 15, 17 | |
|||||||
| 13 | | **Boundary** | at the exact limit | 17, 18, 19 | |
|||||||
| 14 | | **Wrong** | wrong format or type | `"twenty"`, -5 | |
|||||||
| 15 | | **Absent** | missing entirely | `""`, `null` | |
|||||||
| 16 | ||||||||
| 17 | ## Story 1 — the age checker |
|||||||
| 18 | ||||||||
| 19 | Students must be 18 or older to enrol: |
|||||||
| 20 | ||||||||
| 21 | ```gdscript |
|||||||
| 22 | func check_age(age): |
|||||||
| 23 | if age >= 18: |
|||||||
| 24 | return "Eligible for enrolment" |
|||||||
| 25 | return "Too young - must be 18+" |
|||||||
| 26 | ``` |
|||||||
| 27 | ||||||||
| 28 | Fill in an appropriate age for each row, then run them: |
|||||||
| 29 | ||||||||
| 30 | | Test ID | Description | Test data type | Input | Expected output | Actual output | Result | |
|||||||
| 31 | |---|---|---|---|---|---|---| |
|||||||
| 32 | | TC001 | Valid adult age | Valid | age = | "Eligible for enrolment" | "Eligible for enrolment" | ✅ Pass | |
|||||||
| 33 | | TC002 | Older student | Valid but unusual | age = | "Eligible for enrolment" | "Eligible for enrolment" | ✅ Pass | |
|||||||
| 34 | | TC003 | Under-age student | Invalid | age = | "Too young - must be 18+" | "Too young - must be 18+" | ✅ Pass | |
|||||||
| 35 | | TC004 | Minimum age boundary | Boundary | age = | "Eligible for enrolment" | "Eligible for enrolment" | ✅ Pass | |
|||||||
| 36 | | TC005 | Just under boundary | Boundary | age = | "Too young - must be 18+" | "Too young - must be 18+" | ✅ Pass | |
|||||||
| 37 | | TC006 | Text instead of number | Wrong | age = "twenty" | Error message | **Game crashes** | ❌ Fail | |
|||||||
| 38 | | TC007 | Missing age | Absent | age = null | Error message | **Game crashes** | ❌ Fail | |
|||||||
| 39 | ||||||||
| 40 | >| ### Answer |
|||||||
| 41 | >| | Test ID | Suggested age | Reasoning | |
|||||||
| 42 | >| |---|---|---| |
|||||||
| 43 | >| | TC001 | 20 | normal adult student | |
|||||||
| 44 | >| | TC002 | 65 | unusual but perfectly valid | |
|||||||
| 45 | >| | TC003 | 13 | clearly under the minimum | |
|||||||
| 46 | >| | TC004 | 18 | exactly at the boundary — minimum valid | |
|||||||
| 47 | >| | TC005 | 17 | one below the boundary | |
|||||||
| 48 | ||||||||
| 49 | 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. |
|||||||
| 50 | ||||||||
| 51 | ## Story 2 — the GPA calculator (practice) |
|||||||
| 52 | ||||||||
| 53 | A GPA calculator that validates its inputs and decides graduation eligibility (needs GPA ≥ 2.0 *and* ≥ 120 credits): |
|||||||
| 54 | ||||||||
| 55 | ```gdscript |
|||||||
| 56 | func calculate_gpa(student_id, grades: Array, credits: Array): |
|||||||
| 57 | if not str(student_id).is_valid_int() or str(student_id).length() != 8: |
|||||||
| 58 | return {"error": "Invalid student ID"} |
|||||||
| 59 | if grades.size() != credits.size(): |
|||||||
| 60 | return {"error": "Grades and credits must match"} |
|||||||
| 61 | var total_points := 0.0 |
|||||||
| 62 | var total_credits := 0 |
|||||||
| 63 | for i in grades.size(): |
|||||||
| 64 | if grades[i] < 0 or grades[i] > 100: |
|||||||
| 65 | return {"error": "Grade %s out of range" % grades[i]} |
|||||||
| 66 | var points := 0.0 |
|||||||
| 67 | if grades[i] >= 80: points = 4.0 |
|||||||
| 68 | elif grades[i] >= 70: points = 3.0 |
|||||||
| 69 | elif grades[i] >= 60: points = 2.0 |
|||||||
| 70 | total_points += points * credits[i] |
|||||||
| 71 | total_credits += credits[i] |
|||||||
| 72 | if total_credits == 0: |
|||||||
| 73 | return {"error": "No credits provided"} |
|||||||
| 74 | var gpa := total_points / total_credits |
|||||||
| 75 | if gpa >= 2.0 and total_credits >= 120: |
|||||||
| 76 | return {"status": "graduate", "gpa": snapped(gpa, 0.01)} |
|||||||
| 77 | return {"status": "not ready", "gpa": snapped(gpa, 0.01)} |
|||||||
| 78 | ``` |
|||||||
| 79 | ||||||||
| 80 | > [!NOTE] |
|||||||
| 81 | > **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. |
|||||||
| 82 | ||||||||
| 83 | | Test ID | Test data type | Input | Expected output | Actual output | Result | |
|||||||
| 84 | |---|---|---|---|---|---| |
|||||||
| 85 | | TC001 | Valid | ID=12345678, grades=[85,90], credits=[3,3] | {"status": "graduate", "gpa": 4.0} | {"status": "not ready", "gpa": 4.0} | ❌ Fail | |
|||||||
| 86 | | TC002 | Valid | | | | | |
|||||||
| 87 | | TC003 | Valid but unusual | ID=87654321, grades=[60,80], credits=[60,60] | {"status": "graduate", "gpa": 3.5} | {"status": "graduate", "gpa": 3.0} | ❌ Fail | |
|||||||
| 88 | | TC004 | Valid but unusual | | | | | |
|||||||
| 89 | | TC005 | Invalid | ID=11111111, grades=[50,40], credits=[3,3] | {"status": "not ready", "gpa": 0.0} | {"status": "not ready", "gpa": 0.0} | ✅ Pass | |
|||||||
| 90 | | TC006 | Invalid | | | | | |
|||||||
| 91 | | TC007 | Boundary | ID=22222222, grades=[70,70], credits=[60,60] | {"status": "graduate", "gpa": 2.0} | {"status": "graduate", "gpa": 3.0} | ❌ Fail | |
|||||||
| 92 | | TC008 | Boundary | | | | | |
|||||||
| 93 | | TC009 | Wrong | ID="ABCD1234", grades=[80], credits=[3] | {"error": "Invalid student ID"} | {"error": "Invalid student ID"} | ✅ Pass | |
|||||||
| 94 | | TC010 | Wrong | | | | | |
|||||||
| 95 | | TC011 | Absent | ID=55555555, grades=[], credits=[] | {"error": "No credits provided"} | {"error": "No credits provided"} | ✅ Pass | |
|||||||
| 96 | | TC012 | Absent | | | | | |
|||||||
| 97 | ||||||||
| 98 | > [!WARNING] |
|||||||
| 99 | > **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. |
|||||||
| 100 | ||||||||
| 101 | **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. |
|||||||
