Testing & Verification

Table of Contents

  1. Gameplay Testing
  2. Integration Testing
  3. API Error Handling

Testing means systematically checking that your program works correctly — gameplay, API integration, and error handling all need to be verified before a project is complete.

Subrequirements

Gameplay Testing

What was learned: Gameplay testing means playing through the entire game to verify that level completion, character interactions, and collision detection all work without critical bugs. Testing Pong end-to-end caught a bug where the win screen never triggered when a player reached exactly 11 points because of an off-by-one in the score comparison.
Evidence:
  • Pong Game: Played through full rounds to verify win condition, multi-ball power-up timing, and paddle clamping at canvas edges (View Pong Game)
  • Snake Game: Tested collision with self and walls, food spawning on empty cells, and score incrementing correctly (View Snake Game)
// From hacks/pong.md — checkWin() must fire when score reaches exactly winningScore
// Bug found during gameplay test: was using > instead of >=
checkWin() {
    if (this.scores.p1 >= Config.rules.winningScore ||   // ← >= catches exact match
        this.scores.p2 >= Config.rules.winningScore) {
        this.gameOver = true;
        return true;
    }
    return false;
}

// From hacks/snake.md — self-collision test verifies head doesn't match any body segment
const selfCollision = this.segments.slice(1).some(
    seg => seg.x === this.head.x && seg.y === this.head.y
);

Code Runner Challenge

Hit Run to see an automated gameplay test suite — the same checks you'd perform manually when play-testing Pong and Snake. Each test logs PASS or FAIL with the values it checked.

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Quick Quiz: Gameplay Testing

  1. Why is it important to test your game by actually playing it?
    • a) To make sure it looks good
    • b) To find bugs and verify everything works as expected
    • c) To show off to friends
  2. What bug was found in Pong’s win condition?
  3. How can automated tests help you?
Show Answers 1. b) To find bugs and verify everything works as expected 2. The win screen didn’t trigger when a player reached exactly 11 points (off-by-one error). 3. They catch problems quickly and make sure changes don’t break existing features.

Integration Testing

What was learned: Integration testing checks that separate parts of the system work correctly together — like the game front-end talking to the leaderboard API and the NPC AI backend. A full integration test verifies that a score submitted from the game actually appears on the leaderboard, not just that the fetch call returns 200.
Evidence:
  • Local Storage Demo: Ran a complete coin-collection → score-submit → leaderboard-display flow to confirm end-to-end data persistence (Local Storage Demo)
  • Collision Mechanics Level: Tested that player-NPC collision triggers the dialogue system and the correct message displays, not just that collides() returns true (Collision Demo)
// From _projects/local-storage/levels/localStorageDemo.js — integration flow
// Integration test: coin collected → event fired → score submitted → leaderboard updated

// Step 1: coin triggers event
document.dispatchEvent(new CustomEvent('coinCollected', { detail: { total: 5 } }));

// Step 2: leaderboard listener submits score (must reach actual backend)
document.addEventListener('coinCollected', async (e) => {
    const result = await leaderboard.submitScore('TestPlayer', e.detail.total, 'CoinsCollected');
    // Step 3: verify response confirms save (not just 200 status)
    console.assert(result.status === 'ok', 'Expected status ok, got:', result.status);
});

Code Runner Challenge

Hit Run to see a full integration test that chains two systems together — a simulated coin event flowing through to an actual API call and a verified response. This mirrors the Local Storage Demo leaderboard integration test.

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

API Error Handling

What was learned: API error handling means wrapping fetch calls in try/catch blocks and handling network failures gracefully so the game doesn't crash when the backend is unavailable. Adding error handling to the leaderboard submit made the game resilient — a network failure shows a soft warning in the console instead of throwing an uncaught exception that freezes the game loop.
Evidence:
// From _projects/local-storage/levels/localStorageDemo.js — error handling for API
leaderboard.submitScore(playerName, total, 'CoinsCollected').catch(err => {
    console.warn('[Leaderboard] submitScore failed:', err);
    // Game continues — error is contained, not propagated
});

// Full try/catch pattern for fetch calls
async function safeSubmit(name, score) {
    try {
        const res = await fetch('/api/leaderboard', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ name, score })
        });
        if (!res.ok) throw new Error('HTTP ' + res.status + ' ' + res.statusText);
        return await res.json();
    } catch (err) {
        console.warn('[API] Submit failed:', err.message);
        return null;   // ← return null instead of crashing
    }
}

Code Runner Challenge

Hit Run to see API error handling — try/catch wrapping all fetch calls so network failures are logged, not re-thrown. This is the exact pattern from localStorageDemo.js that keeps the game running even when the backend is down.

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Gamerunner — Test-Driven Pong

This Pong game runs a live self-test on load — it checks win condition logic, wall bounce, and score tracking before the game starts. Press T at any time to re-run the test suite. Use W/S and Arrow keys to play.

Challenge

Pong with live self-test suite verifying gameplay mechanics

Lines: 1 Characters: 0
Game Status: Not Started