Single Source of Truth for Testing Procedures, Patterns, and Tracking
Last Updated: October 10, 2025
Status: Active
Purpose: Central hub for test discoverability and comprehensive testing guidance
New to testing FerrisScript? Start here:
cargo test --workspace or ferris-test --allLooking for specific test coverage? β See Test Matrices
FerrisScript uses a 4-layer testing strategy where each layer validates different concerns:
βββββββββββββββββββββββββββββββββββββββββββββββ
β Layer 4: Manual Testing (Godot Editor) β β Feature validation
βββββββββββββββββββββββββββββββββββββββββββββββ€
β Layer 3: Integration Tests (.ferris) β β End-to-end behavior
βββββββββββββββββββββββββββββββββββββββββββββββ€
β Layer 2: GDExtension Tests (GDScript) β β Godot bindings
βββββββββββββββββββββββββββββββββββββββββββββββ€
β Layer 1: Unit Tests (Rust) β β Pure logic
βββββββββββββββββββββββββββββββββββββββββββββββ
| Test Type | Count | Location | Run Command |
|---|---|---|---|
| Unit Tests (Compiler) | 543 | crates/compiler/src/ |
cargo test -p ferrisscript_compiler |
| Unit Tests (Runtime) | 110 | crates/runtime/src/ |
cargo test -p ferrisscript_runtime |
| Unit Tests (GDExtension) | 11 pass, 10 ignored | crates/godot_bind/src/ |
cargo test -p ferrisscript_godot_bind |
| Integration Tests | 15+ | godot_test/scripts/*.ferris |
ferris-test --all |
| Benchmark Tests | 8 suites | crates/*/benches/ |
cargo bench |
| Total | 843+ | All layers | cargo test --workspace |
Coverage: ~82% (last updated: 2025-10-10)
What: Tests lexer, parser, type checker, and code generator logic
When: Testing pure compilation logic without runtime execution
Location: crates/compiler/src/ (inline #[cfg(test)] mod tests)
Documentation:
Quick Start:
# Run all compiler tests (543 tests)
cargo test -p ferrisscript_compiler
# Run specific test
cargo test -p ferrisscript_compiler test_parse_assignment
# Run with output
cargo test -p ferrisscript_compiler -- --show-output
Example Test:
#[test]
fn test_parse_assignment() {
let source = "let x = 42;";
let result = Parser::parse(source);
assert!(result.is_ok());
assert_eq!(result.unwrap().statements.len(), 1);
}
What: Tests AST interpreter, runtime execution, and node callbacks
When: Testing runtime behavior without Godot GDExtension
Location: crates/runtime/src/ and crates/runtime/tests/
Documentation:
Quick Start:
# Run all runtime tests (110 tests)
cargo test -p ferrisscript_runtime
# Run specific test
cargo test -p ferrisscript_runtime test_call_get_node_function
# Run with output
cargo test -p ferrisscript_runtime -- --show-output
Example Test:
#[test]
fn test_call_get_node_function() {
let mut runtime = Runtime::new();
runtime.set_node_callback(|path| Ok(MockNode::new(path)));
let result = runtime.call_function("get_node", vec!["Player"]);
assert!(result.is_ok());
}
What: End-to-end testing of .ferris scripts running in Godot
When: Testing complete feature workflows with real Godot runtime
Location: godot_test/scripts/*.ferris
Tool: ferris-test CLI (from crates/test_harness)
Documentation:
Quick Start:
# Run all integration tests (15+ tests)
ferris-test --all
# Run specific test
ferris-test --script godot_test/scripts/export_properties_test.ferris
# Filter by name
ferris-test --all --filter "signal"
# Verbose output
ferris-test --all --verbose
# JSON format (for CI)
ferris-test --all --format json > results.json
Example Test (godot_test/scripts/signal_test.ferris):
// TEST: signal_emission
// CATEGORY: integration
// EXPECT: success
// ASSERT: Signal emitted correctly
export fn _ready() {
print("[TEST_START]");
signal health_changed(i32, i32);
emit_signal("health_changed", 100, 80);
print("[PASS] Signal emitted successfully");
print("[TEST_END]");
}
Configuration: ferris-test.toml in workspace root
What: Tests Rust code that requires Godot runtime initialization
When: Testing GDExtension bindings, Godot type construction, PropertyInfo generation
Location: crates/*/tests/headless_integration.rs + godot_test/scripts/*.gd
Documentation:
Quick Start:
# Run headless tests (requires Godot)
cargo test -p ferrisscript_godot_bind test_headless_integration
# Note: Some tests are marked #[ignore] because they require Godot runtime
# These are tested via integration tests with ferris-test instead
Example Test:
#[test]
#[ignore = "requires Godot runtime - tested via ferris-test"]
fn test_export_range_property() {
godot::init();
let hint = PropertyHint::Range { min: 0, max: 100, step: 1 };
let result = map_hint(&hint);
assert_eq!(result.hint_string(), "0,100,1");
}
Why Ignored? Many GDExtension tests require godot::init() which canβt run in standard unit tests. These are covered by integration tests instead. See TESTING_GUIDE.md - Why Some Tests Are Ignored for details.
What: Performance benchmarks using Criterion.rs
When: Measuring compiler/runtime performance, regression detection
Location: crates/*/benches/
Documentation:
Quick Start:
# Run all benchmarks
cargo bench
# Run specific benchmark
cargo bench --bench compilation
# Run with baseline comparison
cargo bench -- --save-baseline main
cargo bench -- --baseline main
Benchmark Suites:
compilation - Full pipeline benchmarkslexer - Tokenization performanceparser - AST construction performancetype_checker - Type checking performanceexecution - Runtime execution performanceBaselines: See BENCHMARK_BASELINE.md for v0.0.4 performance targets
Test matrices provide systematic tracking of test scenarios across all test types. Use these to:
Files:
Coverage Summary (as of v0.0.4):
| Feature Category | Total Scenarios | Tested | Coverage | Priority Gaps |
|---|---|---|---|---|
| Node Query Functions | 45 | 23 | 51% | Relative/absolute paths, Unicode paths, edge cases |
| Signal System | 30 | 18 | 60% | Error propagation, signal validation, performance |
| Overall | 75 | 41 | 55% | Cross-cutting concerns (security, performance) |
| Status Legend: β PASS | β οΈ PARTIAL | β TODO | π§ IN PROGRESS | π₯ FAIL |
Quick Links:
get_node(), get_parent(), has_node(), find_child()signal, emit_signal, error casesPlanned (as features are added):
TEST_MATRIX_ARRAYS_COLLECTIONS.md - Array operations, for loops, iteration (v0.0.6)TEST_MATRIX_GODOT_API.md - Godot API bindings, node lifecycle (v0.0.7)TEST_MATRIX_TYPE_SYSTEM.md - Extended types, casting, type safety (v0.2.0)TEST_MATRIX_ARITHMETIC_SAFETY.md - Checked/saturating/wrapping methods (v0.3.0)Want to add a test matrix? Follow the pattern in TEST_MATRIX_NODE_QUERIES_SIGNALS.md and update this README.
Purpose: Run .ferris integration tests headlessly with Godot
Location: crates/test_harness/src/main.rs
Configuration: ferris-test.toml in workspace root
Features:
Documentation:
Usage Examples:
# Basic usage
ferris-test --all
# Filter tests
ferris-test --all --filter "export"
# JSON output for CI
ferris-test --all --format json > results.json
# Verbose debugging
ferris-test --all --verbose
# Single test
ferris-test --script godot_test/scripts/signal_test.ferris
Configuration (ferris-test.toml):
godot_executable = "path/to/godot.exe"
project_path = "./godot_test"
timeout_seconds = 30
output_format = "console"
verbose = false
Environment Overrides:
GODOT_BIN - Override Godot executable pathGODOT_PROJECT_PATH - Override project pathGODOT_TIMEOUT - Override timeout (seconds)Use this checklist when adding new functionality:
#[cfg(test)] mod tests for pure logic.ferris script in godot_test/scripts/crates/*/tests/headless_integration.rs if requiring Godot runtime#[ignore] with reason if Godot init requiredcrates/*/benches/.github/workflows/)Problem: βTests pass locally but fail in CIβ
Problem: βGDExtension not loaded in testsβ
cargo build --release, verify ferrisscript.gdextension pathsProblem: βferris-test command not foundβ
cargo build --release in test_harness crate, or use cargo run --bin ferris-test -- --allProblem: βTest marked as failed but output looks correctβ
--verboseProblem: Copilot suggests creating duplicate testing infrastructure
Full Troubleshooting: See TESTING_GUIDE.md - Troubleshooting
ferris-test and test_harness instead of creating new toolsUpdate Frequency: After each version release or when testing patterns change
Review Triggers:
Ownership: Project Lead (solo dev) + Community Contributors
Last Review: October 10, 2025 (v0.0.4 completion)
Questions or Issues? See CONTRIBUTING.md or open a GitHub issue.
Want to improve testing? Check TEST_HARNESS_TESTING_STRATEGY.md for enhancement opportunities.