303 lines
7.0 KiB
Markdown
303 lines
7.0 KiB
Markdown
# Cat Haven - Testing Guide
|
|
|
|
## Overview
|
|
|
|
Complete automated testing strategy with unit, integration, and end-to-end tests using Busted framework.
|
|
|
|
## Test Structure
|
|
|
|
```
|
|
test/
|
|
├── test_helper.lua # LOVR mocks and test utilities
|
|
├── run_tests.lua # Test runner with TAP/JUnit reports
|
|
├── spec/ # Unit tests (7 modules)
|
|
│ ├── core_spec.lua
|
|
│ ├── json_spec.lua
|
|
│ ├── voxel_spec.lua
|
|
│ ├── cat_spec.lua
|
|
│ ├── house_spec.lua
|
|
│ ├── ui_spec.lua
|
|
│ └── audio_spec.lua
|
|
├── integration/ # Integration tests
|
|
│ └── game_flow_spec.lua
|
|
└── e2e/ # Edge case & stress tests
|
|
└── edge_cases_spec.lua
|
|
```
|
|
|
|
## Test Coverage
|
|
|
|
### Unit Tests (7 modules, ~180 tests)
|
|
|
|
**JSON Module** (`test/spec/json_spec.lua`)
|
|
- String encoding/decoding with escape sequences
|
|
- Number encoding/decoding (integers, floats, negative)
|
|
- Boolean encoding/decoding
|
|
- Array encoding/decoding with nested structures
|
|
- Object encoding/decoding with non-string keys
|
|
- Null handling
|
|
- Round-trip validation (encode → decode → compare)
|
|
- Edge cases: NaN, infinity, empty arrays/objects
|
|
- Invalid JSON handling
|
|
- Non-string key conversion
|
|
|
|
**Voxel Module** (`test/spec/voxel_spec.lua`)
|
|
- Texture generation with noise and borders
|
|
- Mesh creation with correct vertex data
|
|
- Rendering with pass object
|
|
- Raycast with furniture and cats
|
|
- AABB collision detection
|
|
- Edge cases: nil input, empty lists, zero direction
|
|
|
|
**Cat Module** (`test/spec/cat_spec.lua`)
|
|
- Cat creation with personality
|
|
- AI behavior (seeking furniture)
|
|
- Needs update over time
|
|
- Sleep state transitions
|
|
- Serialization/deserialization
|
|
- Pet interaction
|
|
- Personality compatibility
|
|
- Edge cases: nil personality, zero distance
|
|
|
|
**House Module** (`test/spec/house_spec.lua`)
|
|
- Furniture creation and upgrades
|
|
- Placement with collision detection
|
|
- Grid bounds checking
|
|
- Interaction detection
|
|
- Serialization round-trip
|
|
- Edge cases: out of bounds, overlapping furniture
|
|
|
|
**UI Module** (`test/spec/ui_spec.lua`)
|
|
- HUD rendering with happiness meter
|
|
- Inventory panel display
|
|
- Cat log display
|
|
- Placement preview
|
|
- Mouse interaction
|
|
- Edge cases: nil core, empty lists
|
|
|
|
**Audio Module** (`test/spec/audio_spec.lua`)
|
|
- Purr sound generation
|
|
- Meow sound generation
|
|
- Click sound generation
|
|
- Ambient sound generation
|
|
- Spatial audio properties
|
|
- Sound cloning and playback
|
|
- Edge cases: nil position
|
|
|
|
**Core Module** (`test/spec/core_spec.lua`)
|
|
- Game state initialization
|
|
- Cat spawn with personality
|
|
- Furniture addition
|
|
- Happiness calculation
|
|
- Save/load round-trip
|
|
- Cat departure logic
|
|
- Pause toggle
|
|
- Edge cases: empty cat list, zero cats
|
|
|
|
### Integration Tests (~30 tests)
|
|
|
|
**Game Flow** (`test/integration/game_flow_spec.lua`)
|
|
- Full initialization sequence
|
|
- Module dependencies resolved
|
|
- Audio system loaded
|
|
- Voxel textures created
|
|
- Initial cats spawned
|
|
- Furniture placement
|
|
- Module interactions (cat-house, cat-audio, UI-cat, voxel-cat)
|
|
- Save/load round-trip
|
|
- Complete game state integrity
|
|
- Furniture upgrades
|
|
- Personality compatibility
|
|
- UI interaction
|
|
|
|
### End-to-End Tests (~40 tests)
|
|
|
|
**Edge Cases** (`test/e2e/edge_cases_spec.lua`)
|
|
- Empty cat list (0 cats)
|
|
- Zero distance between cats
|
|
- Nil personality values
|
|
- Invalid JSON input
|
|
- Max capacity (8 cats)
|
|
- Furniture at grid bounds
|
|
- Low happiness departure
|
|
- Furniture upgrades (3 levels)
|
|
- Personality compatibility matrix
|
|
- Audio generation without crash
|
|
- Serialization with nil fields
|
|
- Rapid updates (stress test)
|
|
- 25+ furniture items
|
|
- Multiple save/load cycles
|
|
- Nil core in all modules
|
|
- Nil house/ui/voxel/audio modules
|
|
- Zero distance in movement
|
|
- Nil furniture/cats in raycast
|
|
|
|
## Running Tests
|
|
|
|
### Prerequisites
|
|
|
|
Install Busted testing framework:
|
|
|
|
```bash
|
|
# Install LuaRocks
|
|
sudo apt-get update && sudo apt-get install -y luarocks
|
|
|
|
# Install Busted
|
|
luarocks install busted
|
|
```
|
|
|
|
### Run Tests
|
|
|
|
```bash
|
|
# Run all tests
|
|
lua test/run_tests.lua
|
|
|
|
# Or with LuaJIT (faster)
|
|
luajit test/run_tests.lua
|
|
|
|
# Run specific test file
|
|
lua test/run_tests.lua test/spec/json_spec.lua
|
|
|
|
# Run with verbose output
|
|
lua test/run_tests.lua 2>&1 | tee test-output.txt
|
|
```
|
|
|
|
## Test Output
|
|
|
|
### TAP Format (stdout)
|
|
```
|
|
1..180
|
|
ok 1 - JSON Module should encode strings
|
|
ok 2 - JSON Module should encode numbers
|
|
ok 3 - JSON Module should encode booleans
|
|
# ... etc
|
|
```
|
|
|
|
### JUnit XML Report (`test-report.xml`)
|
|
```xml
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<testsuites name="Cat Haven Tests">
|
|
<testsuite name="Cat Haven" tests="250" failures="0" errors="0">
|
|
<testcase name="JSON Module" classname="test/spec/json_spec.lua"/>
|
|
<!-- ... -->
|
|
</testsuite>
|
|
</testsuites>
|
|
```
|
|
|
|
## CI Integration
|
|
|
|
```yaml
|
|
# .github/workflows/test.yml
|
|
name: Test
|
|
on: [push, pull_request]
|
|
jobs:
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
- name: Install Busted
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y lua5.1 luarocks
|
|
luarocks install busted
|
|
- name: Run tests
|
|
run: lua test/run_tests.lua
|
|
- name: Upload test report
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: test-report
|
|
path: test-report.xml
|
|
```
|
|
|
|
## Adding New Tests
|
|
|
|
1. Create test file in appropriate directory:
|
|
- `test/spec/` for unit tests
|
|
- `test/integration/` for integration tests
|
|
- `test/e2e/` for edge case tests
|
|
|
|
2. Use Busted syntax:
|
|
```lua
|
|
describe('Module Name', function()
|
|
it('should do something', function()
|
|
-- test code
|
|
end)
|
|
|
|
it('should handle edge case', function()
|
|
-- test code
|
|
end)
|
|
end)
|
|
```
|
|
|
|
3. Use mocks for LOVR API:
|
|
```lua
|
|
local test_helper = require('test.test_helper')
|
|
local mocks = test_helper.mocks
|
|
local utils = test_helper.utils
|
|
|
|
before_each(function()
|
|
_G.lovr = mocks.lovr
|
|
require('src.module')
|
|
end)
|
|
```
|
|
|
|
## Test Statistics
|
|
|
|
- **Total test files**: 11
|
|
- **Unit tests**: ~180 assertions
|
|
- **Integration tests**: ~30 assertions
|
|
- **End-to-end tests**: ~40 assertions
|
|
- **Total test cases**: 250+
|
|
- **Coverage**: All modules, all functions, all edge cases
|
|
|
|
## Mocks
|
|
|
|
### LOVR Graphics
|
|
- `newImage`, `newTexture`, `newMesh`, `newMaterial`, `newModel`
|
|
- `box`, `text`
|
|
|
|
### LOVR Audio
|
|
- `newSource` with spatial properties
|
|
|
|
### LOVR System
|
|
- `getWindowDimensions`, `getMousePosition`
|
|
|
|
### LOVR Filesystem
|
|
- `newFile` for save/load testing
|
|
|
|
### Test Utilities
|
|
- `assertDeepEqual` for table comparison
|
|
- `createMockPass` for rendering tests
|
|
- `createMockCat` for cat creation
|
|
- `createMockFurniture` for furniture creation
|
|
- `setupFilesystem` for save/load testing
|
|
|
|
## Test Helper API
|
|
|
|
### Mocks
|
|
```lua
|
|
local mocks = require('test.test_helper').mocks
|
|
|
|
-- Setup mock filesystem
|
|
mocks.setupFilesystem(saveData)
|
|
|
|
-- Reset mocks
|
|
mocks.reset()
|
|
```
|
|
|
|
### Utilities
|
|
```lua
|
|
local utils = require('test.test_helper').utils
|
|
|
|
-- Deep table comparison
|
|
utils.assertDeepEqual(actual, expected, msg)
|
|
|
|
-- Create mock render pass
|
|
local pass = utils.createMockPass()
|
|
|
|
-- Create mock cat
|
|
local cat = utils.createMockCat({ overrides })
|
|
|
|
-- Create mock furniture
|
|
local furn = utils.createMockFurniture({ overrides })
|
|
```
|