| name | fix-test-failures |
| description | This skill should be used after running tests when failures occur. It ensures test failures are properly diagnosed through instrumentation and logging until the root cause is found and fixed. The skill treats all test failures as real bugs that must be resolved, never skipped. |
Fix Test Failures
This skill provides a systematic approach to diagnosing and fixing test failures. The core philosophy is that test failures are real bugs - they must be understood and fixed, never ignored or worked around.
NO CHEATING - Critical Tests
These tests validate exact behavioral matching with the C++ AGG implementation. There are no workarounds.
Every test exists because it validates behavior that must match C++ exactly. Bypassing tests means shipping incorrect implementations.
Forbidden actions (no exceptions):
- Weakening assertions to make tests pass
- Changing expected values to match broken behavior
- Wrapping failing code in catch blocks to swallow errors
- Adding conditional logic to skip checks in test environments
- Commenting out assertions or test blocks
- Using
todo!() or unimplemented!() to defer failures
- Relaxing precision requirements to mask numerical errors
- Mocking away the actual behavior being tested
The only acceptable outcome is fixing the actual bug in the production code.
When to Use This Skill
Use this skill when:
- Tests fail and the cause isn't immediately obvious
- A test is flaky or intermittently failing
- You need to understand why a test is failing before fixing it
- You've made changes and tests are now failing
Core Principles
- Test failures are real bugs - Never skip, disable, or delete failing tests without understanding and fixing the underlying issue
- No cheating - Never weaken tests, change expected values, or work around failures
- Instrument to understand - Add print statements to expose internal state and execution flow
- Fix the root cause - Don't patch symptoms; find and fix the actual bug
- Clean up after - Remove instrumentation once the fix is verified
Test Failure Resolution Process
Step 1: Run Tests and Capture Failures
Run the failing test(s) to see the current error:
cargo test
cargo test --lib basics_tests
cargo test test_name -- --exact
cargo test test_name -- --nocapture
RUST_BACKTRACE=1 cargo test test_name -- --nocapture
Record the exact error message and stack trace. This is your starting point.
Step 2: Analyze the Failure
Before adding instrumentation, understand what the test is checking:
- Read the test code carefully
- Identify what assertion is failing
- Note what values were expected vs. received
- Cross-reference with the C++ implementation in
cpp-references/agg-src/
- Form a hypothesis about what might be wrong
Step 3: Add Strategic Instrumentation
Add println! or dbg! statements to expose the state at key points:
For pixel/rendering failures:
println!("Pixel at ({}, {}): rgba({}, {}, {}, {})", x, y, r, g, b, a);
println!("Coverage: {}, Area: {}", cover, area);
For numerical precision failures:
println!("Expected: {:.15}", expected);
println!("Actual: {:.15}", actual);
println!("Diff: {:.15e}", (expected - actual).abs());
For function execution flow:
println!("Entering function with args: {:?}, {:?}", arg1, arg2);
println!("Returning result: {:?}", result);
Step 4: Run Instrumented Tests
Run the test again with output visible:
cargo test test_name -- --nocapture
Step 5: Identify Root Cause
Based on instrumentation output, determine:
- Is the test wrong (rare)?
- Is the code under test wrong (common)?
- Is there a numerical precision issue?
- Is there a type conversion problem?
- Does the Rust implementation diverge from C++ behavior?
Step 6: Fix the Bug
Fix the actual bug in the production code.
Common fixes for this project:
- Blending errors: Verify against C++ pixel blending formulas
- Coverage issues: Check rasterizer cell accumulation
- Precision issues: Check floating point order of operations
- Type mismatches: Ensure proper conversions between color types
- Edge cases: Verify handling of empty paths, degenerate geometry
Step 7: Verify and Clean Up
- Run the test again to confirm it passes
- Run the full test suite to ensure no regressions:
cargo test
- Remove all instrumentation print statements - they were for debugging only
- Commit the fix
Iterative Debugging
If the first round of instrumentation doesn't reveal the issue:
- Add more instrumentation at earlier points in execution
- Log intermediate values, not just final state
- Compare intermediate values with C++ execution
- Check for side effects from other code
- Verify test setup is correct
Keep iterating until the root cause is clear.
C++ Comparison Technique
When stuck, compare execution step-by-step with C++:
- Find the corresponding code in
cpp-references/agg-src/
- Add corresponding print statements in both Rust and C++ code
- Run both with the same input
- Find the first point of divergence
- That divergence point is your bug location
What NOT to Do (NO CHEATING)
- Don't skip failing tests
- Don't delete tests to make the suite pass
- Don't use
#[ignore] as a permanent solution
- Don't weaken assertions
- Don't change expected values to match broken output
- Don't use
todo!() to defer the fix
- Don't relax precision to hide numerical errors
- Don't leave instrumentation in committed code
If you find yourself wanting to do any of these, STOP. The test is telling you something is broken. Fix the broken thing.