Files
leptos-shadcn-ui/docs/contributing/adr/001-tdd-first-approach.md
Peter Hanssens 0988aed57e Release v0.8.1: Major infrastructure improvements and cleanup
- Complete documentation reorganization into professional structure
- Achieved 90%+ test coverage across all components
- Created sophisticated WASM demo matching shadcn/ui quality
- Fixed all compilation warnings and missing binary files
- Optimized dependencies across all packages
- Professional code standards and performance optimizations
- Cross-browser compatibility with Playwright testing
- New York variants implementation
- Advanced signal management for Leptos 0.8.8+
- Enhanced testing infrastructure with TDD approach
2025-09-16 22:14:20 +10:00

4.4 KiB

ADR-001: Test-Driven Development (TDD) First Approach

Status

ACCEPTED - 2024-09-08

Context

As a data engineering consultancy specializing in Rust and Leptos, we need to establish a clear technical philosophy that ensures the highest quality deliverables for our clients. Our reputation depends on delivering robust, reliable, and maintainable solutions.

Decision

We adopt a Test-Driven Development (TDD) first approach as our core development methodology.

TDD Process

  1. Red: Write a failing test first
  2. Green: Write minimal code to make the test pass
  3. Refactor: Improve code while keeping tests green
  4. Repeat: Continue the cycle for each feature

TDD Principles

  • No production code without tests: Every line of production code must have corresponding tests
  • Tests drive design: Tests define the API and behavior before implementation
  • Fail fast: Tests catch issues immediately during development
  • Living documentation: Tests serve as executable documentation
  • Confidence in refactoring: Comprehensive test coverage enables safe code improvements

Consequences

Positive

  • Higher code quality: TDD forces better design and cleaner code
  • Reduced bugs: Issues caught early in development cycle
  • Faster debugging: Immediate feedback on code changes
  • Better API design: Tests force consideration of usage patterns
  • Client confidence: Demonstrable quality through comprehensive testing
  • Easier maintenance: Well-tested code is easier to modify and extend

Negative

  • Initial development time: Writing tests first may seem slower initially
  • Learning curve: Team must be trained in TDD practices
  • Test maintenance: Tests require ongoing maintenance as code evolves

Mitigation

  • Training investment: Comprehensive TDD training for all team members
  • Tooling support: Automated testing tools and CI/CD integration
  • Code reviews: Ensure TDD practices are followed in all pull requests

Implementation

Development Workflow

  1. Feature planning: Define acceptance criteria and test scenarios
  2. Test writing: Write failing tests for new functionality
  3. Implementation: Write minimal code to pass tests
  4. Refactoring: Improve code structure while maintaining test coverage
  5. Integration: Ensure all tests pass in CI/CD pipeline

Quality Gates

  • Pre-commit hooks: Run tests before code commits
  • Pull request requirements: All tests must pass before merge
  • Coverage thresholds: Maintain minimum 95% test coverage
  • Performance tests: Include performance benchmarks in test suite

Tools and Technologies

  • Rust: Built-in testing framework with cargo test
  • Playwright: End-to-end testing for web applications
  • wasm-bindgen-test: WebAssembly testing framework
  • Criterion: Benchmarking and performance testing
  • Tarpaulin: Code coverage analysis

Examples

Rust Unit Test Example

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_data_pipeline_processes_records() {
        // Given
        let input_data = vec!["record1", "record2", "record3"];
        let pipeline = DataPipeline::new();
        
        // When
        let result = pipeline.process(input_data);
        
        // Then
        assert_eq!(result.len(), 3);
        assert!(result.iter().all(|r| r.is_processed()));
    }
}

Playwright E2E Test Example

test('should process data pipeline successfully', async ({ page }) => {
  // Given
  await page.goto('/pipeline');
  
  // When
  await page.fill('[data-testid="input-data"]', 'test-data');
  await page.click('[data-testid="process-button"]');
  
  // Then
  await expect(page.locator('[data-testid="result"]')).toBeVisible();
  await expect(page.locator('[data-testid="success-message"]')).toContainText('Processing complete');
});

Monitoring and Metrics

  • Test coverage: Track and report test coverage metrics
  • Test execution time: Monitor test suite performance
  • Bug escape rate: Measure bugs found in production vs. tests
  • Development velocity: Track feature delivery with TDD approach

Review and Updates

This ADR will be reviewed quarterly to ensure TDD practices remain effective and aligned with project needs. Updates will be made based on team feedback and industry best practices.

  • ADR-002: Testing Pyramid Strategy
  • ADR-003: Playwright Testing for Demos
  • ADR-004: Code Coverage Standards