Renderer Testing
Hugo Renderer Testing Strategy
Overview
The Hugo renderer system uses a dual-path testing approach to ensure both the NoopRenderer (for CI/fast tests) and BinaryRenderer (for integration tests) work correctly.
Test Files
renderer_test.go
Purpose: Fast unit tests that don’t require Hugo binary
Key Tests:
TestNoopRenderer: Verifies NoopRenderer marks site as rendered without invoking Hugo- Uses
WithRenderer(&NoopRenderer{})to inject test renderer - Sets
render_mode=alwaysto ensure rendering is attempted - Verifies
StaticRendered=trueeven when Hugo binary is missing
- Uses
renderer_integration_test.go
Purpose: Integration tests that verify actual Hugo execution when available
Key Tests:
-
TestBinaryRenderer_WhenHugoAvailable- Skips if Hugo not in PATH
- Verifies BinaryRenderer invokes real Hugo binary
- Gracefully handles Hugo failures (e.g., missing theme dependencies)
- Checks for
public/directory creation
-
TestBinaryRenderer_MissingHugoBinary- Verifies proper error handling when Hugo unavailable
- Tests the BinaryRenderer error path directly
-
TestRenderMode_Never_SkipsRendering- Verifies
render_mode=neverprevents all rendering - Ensures no
public/directory is created
- Verifies
-
TestRenderMode_Always_WithNoopRenderer- Verifies custom renderer takes precedence
- NoopRenderer should run even with
render_mode=always
-
TestRenderMode_Auto_WithoutEnvVars- Verifies
render_mode=autobehavior - Tests legacy env var handling
- Verifies
-
TestRendererPrecedence- Comprehensive test matrix documenting renderer selection priority
- Tests all combinations of render modes and renderer types
Testing Strategy
CI Environment (No Hugo Binary)
All tests use NoopRenderer to avoid requiring Hugo installation:
Benefits:
- Fast test execution
- No external dependencies
- Tests the rendering pipeline logic
- Verifies
StaticRenderedtracking
Local Development (Hugo Available)
Integration tests automatically detect Hugo and run real rendering:
Benefits:
- Verifies end-to-end Hugo integration
- Catches Hugo-specific issues
- Tests actual static site generation
Renderer Selection Priority
The actual priority (from stage_run_hugo.go):
render_mode=never→ Skip all rendering (return early)- Custom renderer set → Use custom renderer (e.g., NoopRenderer)
shouldRunHugo()check → Evaluate render mode and Hugo availability- Fallback → Use BinaryRenderer with Hugo binary
Adding New Renderer Tests
For Unit Tests (No Hugo Required)
Use NoopRenderer and test the logic:
For Integration Tests (Hugo Required)
Skip when Hugo unavailable:
Common Patterns
Test Renderer Execution Path
Test Hugo Failure Handling
Test Render Mode Behavior
Debugging Test Failures
“Hugo binary not found” in CI
✅ Expected - Use NoopRenderer for CI tests
“StaticRendered=false” with BinaryRenderer
✅ Expected - Hugo may fail without proper theme setup
Check logs for “Renderer execution failed”
“public/ directory exists but StaticRendered=false”
✅ Expected - Hugo creates public/ before failing
This is normal for partial renders
Custom renderer not being used
❌ Problem - Check that WithRenderer() is called
Verify render_mode is not “never”
Best Practices
- Always use NoopRenderer in CI - Don’t depend on Hugo being installed
- Skip integration tests gracefully - Use
t.Skip()when Hugo unavailable - Test the interface, not implementation - Focus on
StaticRenderedandpublic/dir - Handle Hugo failures gracefully - Real Hugo may fail in tests, that’s OK
- Document test expectations - Use clear test names and comments