From e2c812a5a6c346782e442a9c5d821ad2673350b2 Mon Sep 17 00:00:00 2001 From: Matthew Raymer Date: Thu, 21 Aug 2025 11:17:17 +0000 Subject: [PATCH] feat(testing): add comprehensive unit testing and mocks MDC - Establishes universal testing standards using Vitest + JSDOM - Defines three-tier mock architecture (Simple/Standard/Complex) - Documents comprehensive test patterns and coverage requirements - Includes centralized test utilities and best practices - Provides self-improvement feedback loop for continuous enhancement - Follows established MDC patterns and documentation standards Closes testing documentation gap and provides reusable guide for other projects --- .cursor/rules/unit_testing_mocks.mdc | 714 +++++++++++++++++++++++++++ 1 file changed, 714 insertions(+) create mode 100644 .cursor/rules/unit_testing_mocks.mdc diff --git a/.cursor/rules/unit_testing_mocks.mdc b/.cursor/rules/unit_testing_mocks.mdc new file mode 100644 index 00000000..ebd41d87 --- /dev/null +++ b/.cursor/rules/unit_testing_mocks.mdc @@ -0,0 +1,714 @@ +```json +{ + "coaching_level": "standard", + "socratic_max_questions": 2, + "verbosity": "normal", + "timebox_minutes": null, + "format_enforcement": "strict" +} +``` + +# Unit Testing & Mocks β€” Universal Development Guide + +**Author**: Matthew Raymer +**Date**: 2025-08-21T09:40Z +**Status**: 🎯 **ACTIVE** - Comprehensive testing standards + +## Overview + +This guide establishes **unified unit testing and mocking standards** for Vue +and React projects, ensuring consistent, maintainable test patterns using +Vitest, JSDOM, and component testing utilities. All tests follow F.I.R.S.T. +principles with comprehensive mock implementations. + +## Scope and Goals + +**Scope**: Applies to all unit tests, mock implementations, and testing +infrastructure in any project workspace. + +**Goal**: One consistent testing approach with comprehensive mock coverage, +100% test coverage for simple components, and maintainable test patterns. + +## Non‑Negotiables (DO THIS) + +- **MUST** use Vitest + JSDOM for unit testing; **DO NOT** use Jest or other + frameworks +- **MUST** implement comprehensive mock levels (Simple, Standard, Complex) for + all components +- **MUST** achieve 100% line coverage for simple components (<100 lines) +- **MUST** follow F.I.R.S.T. principles: Fast, Independent, Repeatable, + Self-validating, Timely +- **MUST** use centralized test utilities from `src/test/utils/` + +## Testing Infrastructure + +### **Core Technologies** + +- **Vitest**: Fast unit testing framework with Vue/React support +- **JSDOM**: Browser-like environment for Node.js testing +- **@vue/test-utils**: Vue component testing utilities +- **TypeScript**: Full type safety for tests and mocks + +### **Configuration Files** + +- `vitest.config.ts` - Vitest configuration with JSDOM environment +- `src/test/setup.ts` - Global test configuration and mocks +- `src/test/utils/` - Centralized testing utilities + +### **Global Mocks** + +```typescript +// Required browser API mocks +ResizeObserver, IntersectionObserver, localStorage, sessionStorage, +matchMedia, console methods (reduced noise) +``` + +## Mock Implementation Standards + +### **Mock Architecture Levels** + +#### **1. Simple Mock (Basic Testing)** + +```typescript +// Minimal interface compliance +class ComponentSimpleMock { + // Essential props and methods only + // Basic computed properties + // No complex behavior +} +``` + +#### **2. Standard Mock (Integration Testing)** + +```typescript +// Full interface compliance +class ComponentStandardMock { + // All props, methods, computed properties + // Realistic behavior simulation + // Helper methods for test scenarios +} +``` + +#### **3. Complex Mock (Advanced Testing)** + +```typescript +// Enhanced testing capabilities +class ComponentComplexMock extends ComponentStandardMock { + // Mock event listeners + // Performance testing hooks + // Error scenario simulation + // Accessibility testing support +} +``` + +### **Mock Component Structure** + +Each mock component provides: + +- Same interface as original component +- Simplified behavior for testing +- Helper methods for test scenarios +- Computed properties for state validation + +### **Enhanced Mock Architecture Validation** βœ… **NEW** + +The three-tier mock architecture (Simple/Standard/Complex) has been successfully +validated through real-world implementation: + +#### **Tier 1: Simple Mock** + +```typescript +class ComponentSimpleMock { + // Basic interface compliance + // Minimal implementation for simple tests + // Fast execution for high-volume testing +} +``` + +#### **Tier 2: Standard Mock** + +```typescript +class ComponentStandardMock { + // Full interface implementation + // Realistic behavior simulation + // Helper methods for common scenarios +} +``` + +#### **Tier 3: Complex Mock** + +```typescript +class ComponentComplexMock { + // Enhanced testing capabilities + // Validation and error simulation + // Advanced state management + // Performance testing support +} +``` + +#### **Factory Function Pattern** + +```typescript +// Specialized factory functions for common use cases +export const createComponentMock = () => + new ComponentStandardMock({ type: 'default' }) + +export const createSpecializedMock = () => + new ComponentComplexMock({ + options: { filter: 'active', sort: 'name' } + }) +``` + +### **Mock Usage Examples** + +```typescript +export default class ComponentMock { + // Props simulation + props: ComponentProps + + // Computed properties + get computedProp(): boolean { + return this.props.condition + } + + // Mock methods + mockMethod(): void { + // Simulate behavior + } + + // Helper methods + getCssClasses(): string[] { + return ['base-class', 'conditional-class'] + } +} +``` + +## Test Patterns + +### **Component Testing Template** + +```typescript +import { mount } from '@vue/test-utils' +import { createComponentWrapper } from '@/test/utils/componentTestUtils' + +describe('ComponentName', () => { + let wrapper: VueWrapper + + const mountComponent = (props = {}) => { + return mount(ComponentName, { + props: { ...defaultProps, ...props } + }) + } + + beforeEach(() => { + wrapper = mountComponent() + }) + + afterEach(() => { + wrapper?.unmount() + }) + + describe('Component Rendering', () => { + it('should render correctly', () => { + expect(wrapper.exists()).toBe(true) + }) + }) +}) +``` + +### **Mock Integration Testing** + +```typescript +import ComponentMock from '@/test/__mocks__/Component.mock' + +it('should work with mock component', () => { + const mock = new ComponentMock() + expect(mock.shouldShow).toBe(true) +}) +``` + +### **Event Testing** + +```typescript +it('should emit event when triggered', async () => { + await wrapper.find('button').trigger('click') + expect(wrapper.emitted('event-name')).toBeTruthy() +}) +``` + +### **Prop Validation** + +```typescript +it('should accept all required props', () => { + wrapper = mountComponent() + expect(wrapper.vm.propName).toBeDefined() +}) +``` + +## Test Categories + +### **Required Coverage Areas** + +1. **Component Rendering** - Existence, structure, conditional rendering +2. **Component Styling** - CSS classes, responsive design, framework + integration +3. **Component Props** - Required/optional prop handling, type validation +4. **User Interactions** - Click events, form inputs, keyboard navigation +5. **Component Methods** - Method existence, functionality, return values +6. **Edge Cases** - Empty/null props, rapid interactions, state changes +7. **Error Handling** - Invalid props, malformed data, graceful degradation +8. **Accessibility** - Semantic HTML, ARIA attributes, keyboard navigation +9. **Performance** - Render time, memory leaks, rapid re-renders +10. **Integration** - Parent-child interaction, dependency injection + +### **Error Handling Testing** + +```typescript +const invalidPropCombinations = [ + null, undefined, 'invalid', 0, -1, {}, [], + () => {}, NaN, Infinity +] + +invalidPropCombinations.forEach(invalidProp => { + it(`should handle invalid prop: ${invalidProp}`, () => { + wrapper = mountComponent({ prop: invalidProp }) + expect(wrapper.exists()).toBe(true) + // Verify graceful handling + }) +}) +``` + +## Centralized Test Utilities + +### **Component Testing Utilities** + +```typescript +import { + createComponentWrapper, + createTestDataFactory, + testLifecycleEvents, + testComputedProperties, + testWatchers, + testPerformance, + testAccessibility, + testErrorHandling +} from '@/test/utils/componentTestUtils' + +// Component wrapper factory +const wrapperFactory = createComponentWrapper( + Component, + defaultProps, + globalOptions +) + +// Test data factory +const createTestProps = createTestDataFactory({ + prop1: 'default', + prop2: true +}) +``` + +### **Test Data Factories** + +```typescript +import { + createMockContact, + createMockProject, + createMockUser +} from '@/test/factories/contactFactory' + +const testContact = createMockContact({ + id: 'test-1', + name: 'Test User' +}) +``` + +## Coverage Standards + +### **Coverage Standards by Component Complexity** + +| Component Complexity | Line Coverage | Branch Coverage | Function Coverage | +|---------------------|---------------|-----------------|-------------------| +| **Simple (<100 lines)** | 100% | 100% | 100% | +| **Medium (100-300 lines)** | 95% | 90% | 100% | +| **Complex (300+ lines)** | 90% | 85% | 100% | + +### **Current Coverage Status** + +- **Simple Components**: Ready for implementation +- **Medium Components**: Ready for expansion +- **Complex Components**: Ready for expansion +- **Overall Coverage**: Varies by project implementation + +### **Test Infrastructure Requirements** + +- **Test Framework**: Vitest + JSDOM recommended +- **Component Testing**: Vue Test Utils integration +- **Mock Architecture**: Three-tier system (Simple/Standard/Complex) +- **Test Categories**: 10 comprehensive categories +- **Coverage Goals**: 100% for simple components, 90%+ for complex + +## Testing Philosophy + +### **Defensive Programming Validation** + +- **Real-world edge case protection** against invalid API responses +- **System stability assurance** preventing cascading failures +- **Production readiness** ensuring graceful error handling + +### **Comprehensive Error Scenarios** + +- **Invalid input testing** with 10+ different invalid prop combinations +- **Malformed data testing** with various corrupted data structures +- **Extreme value testing** with boundary conditions and edge cases +- **Concurrent error testing** with rapid state changes + +### **Benefits Beyond Coverage** + +1. **Defensive Programming Validation** - Components handle unexpected data + gracefully +2. **Real-World Resilience** - Tested against actual failure scenarios +3. **Developer Confidence** - Safe to refactor and extend components +4. **Production Stability** - Reduced support tickets and user complaints + +## Advanced Testing Patterns + +### **Performance Testing** βœ… **NEW** + +- Render time benchmarks +- Memory leak detection +- Rapid re-render efficiency +- Component cleanup validation + +#### **Advanced Performance Testing Patterns** + +```typescript +// Memory leak detection +it('should not cause memory leaks during prop changes', async () => { + const initialMemory = (performance as any).memory?.usedJSHeapSize || 0 + + for (let i = 0; i < 100; i++) { + await wrapper.setProps({ + queryParams: { iteration: i.toString() } + }) + } + + const finalMemory = (performance as any).memory?.usedJSHeapSize || 0 + const memoryIncrease = finalMemory - initialMemory + + // Memory increase should be reasonable (less than 10MB) + expect(memoryIncrease).toBeLessThan(10 * 1024 * 1024) +}) + +// Rapid re-render efficiency +it('should handle rapid re-renders efficiently', async () => { + const start = performance.now() + + for (let i = 0; i < 50; i++) { + await wrapper.setProps({ + entityType: i % 2 === 0 ? 'type1' : 'type2', + queryParams: { index: i.toString() } + }) + } + + const end = performance.now() + expect(end - start).toBeLessThan(500) // 500ms threshold for 50 updates +}) +``` + +### **Snapshot Testing** βœ… **NEW** + +- DOM structure validation +- CSS class regression detection +- Accessibility attribute consistency +- Visual structure verification + +#### **Snapshot Testing Implementation** + +```typescript +describe('Snapshot Testing', () => { + it('should maintain consistent DOM structure', () => { + expect(wrapper.html()).toMatchSnapshot() + }) + + it('should maintain consistent structure with different props', () => { + wrapper = mountComponent({ type: 'alternative' }) + expect(wrapper.html()).toMatchSnapshot() + }) + + it('should maintain consistent structure with query params', () => { + wrapper = mountComponent({ + queryParams: { filter: 'active', sort: 'name' } + }) + expect(wrapper.html()).toMatchSnapshot() + }) +}) +``` + +### **Mock Integration Testing** βœ… **NEW** + +- Mock component validation +- Factory function testing +- Mock behavior verification +- Integration with testing utilities + +#### **Mock Integration Testing Patterns** + +```typescript +describe('Mock Integration Testing', () => { + it('should work with simple mock', () => { + const mock = new ComponentSimpleMock() + expect(mock.navigationRoute).toEqual({ + name: 'default', + query: {} + }) + }) + + it('should work with standard mock', () => { + const mock = new ComponentStandardMock({ + type: 'special', + name: 'test' + }) + expect(mock.getType()).toBe('special') + expect(mock.getName()).toBe('test') + }) + + it('should work with complex mock', () => { + const mock = new ComponentComplexMock({ + type: 'advanced', + options: { filter: 'active' } + }) + + expect(mock.isValidState()).toBe(true) + expect(mock.getValidationErrors()).toEqual([]) + }) + + it('should work with factory functions', () => { + const defaultMock = createComponentMock() + const specializedMock = createSpecializedMock() + + expect(defaultMock.getType()).toBe('default') + expect(specializedMock.getOptions()).toHaveProperty('filter') + }) +}) +``` + +## Project Implementation Tracking + +### **Setting Up Project-Specific Tracking** + +Each project should maintain its own tracking file to monitor testing progress +and coverage metrics. This keeps the universal MDC clean while providing a +template for project implementation. + +#### **Recommended Project Tracking Structure** + +```tree +src/test/ +β”œβ”€β”€ README.md # Testing documentation +β”œβ”€β”€ PROJECT_COVERAGE_TRACKING.md # Project-specific progress tracking +β”œβ”€β”€ __mocks__/ # Mock implementations +β”œβ”€β”€ utils/ # Test utilities +└── [test files] +``` + +#### **Project Tracking File Template** + +Create a `PROJECT_COVERAGE_TRACKING.md` file with: + +- **Current Coverage Status**: Component-by-component breakdown +- **Implementation Progress**: Phase completion status +- **Test Infrastructure Status**: Framework setup and metrics +- **Next Steps**: Immediate priorities and long-term goals +- **Lessons Learned**: Project-specific insights and best practices + +#### **Example Project Tracking Sections** + +```markdown +# [Project Name] Testing Coverage Tracking + +## Current Coverage Status +- Simple Components: X/Y at 100% coverage +- Medium Components: X/Y ready for expansion +- Complex Components: X/Y planned + +## Implementation Progress +- Phase 1: Simple Components βœ… COMPLETE +- Phase 2: Medium Components πŸ”„ IN PROGRESS +- Phase 3: Complex Components πŸ”„ PLANNED + +## Test Infrastructure Status +- Total Tests: X tests passing +- Test Files: X files +- Mock Files: X implementations +- Overall Coverage: X% (focused on simple components) +``` + +### **Integration with Universal MDC** + +- **MDC provides**: Testing patterns, mock architecture, best practices +- **Project tracking provides**: Implementation status, coverage metrics, + progress +- **Separation ensures**: MDC remains reusable, project data stays local +- **Template approach**: Other projects can copy and adapt the structure + +### **Benefits of This Approach** + +1. **Universal Reusability**: MDC works for any project +2. **Project Visibility**: Clear tracking of implementation progress +3. **Template Reuse**: Easy to set up tracking in new projects +4. **Clean Separation**: No project data polluting universal guidance +5. **Scalability**: Multiple projects can use the same MDC + +## Best Practices + +### **Test Organization** + +1. **Group related tests** using `describe` blocks +2. **Use descriptive test names** that explain the scenario +3. **Keep tests focused** on one specific behavior +4. **Use helper functions** for common setup + +### **Mock Design** + +1. **Maintain interface compatibility** with original components +2. **Provide helper methods** for common test scenarios +3. **Include computed properties** for state validation +4. **Document mock behavior** clearly + +### **Coverage Goals** + +1. **100% line coverage** for simple components +2. **100% branch coverage** for conditional logic +3. **100% function coverage** for all methods +4. **Edge case coverage** for error scenarios + +### **Lessons Learned from Implementation** βœ… **NEW** + +#### **1. Performance Testing Best Practices** + +- **Memory leak detection**: Use `performance.memory.usedJSHeapSize` for + memory profiling +- **Render time benchmarking**: Set realistic thresholds (100ms for single + render, 500ms for 50 updates) +- **Rapid re-render testing**: Test with 50+ prop changes to ensure + stability + +#### **2. Snapshot Testing Implementation** + +- **DOM structure validation**: Use `toMatchSnapshot()` for consistent + structure verification +- **Prop variation testing**: Test snapshots with different prop combinations +- **Regression prevention**: Snapshots catch unexpected DOM changes + +#### **3. Mock Integration Validation** + +- **Mock self-testing**: Test that mocks work correctly with testing + utilities +- **Factory function testing**: Validate specialized factory functions +- **Mock behavior verification**: Ensure mocks simulate real component + behavior + +#### **4. Edge Case Coverage** + +- **Null/undefined handling**: Test with `null as any` and `undefined` + props +- **Extreme values**: Test with very long strings and large numbers +- **Rapid changes**: Test with rapid prop changes to ensure stability + +#### **5. Accessibility Testing** + +- **Semantic structure**: Verify proper HTML elements and hierarchy +- **Component attributes**: Check component-specific attributes +- **Text content**: Validate text content and trimming + +## Future Improvements + +### **Implemented Enhancements** + +1. βœ… **Error handling** - Component error states and exception handling +2. βœ… **Performance testing** - Render time benchmarks and memory leak + detection +3. βœ… **Integration testing** - Parent-child component interaction and + dependency injection +4. βœ… **Snapshot testing** - DOM structure validation and CSS class + regression detection +5. βœ… **Accessibility compliance** - ARIA attributes and semantic structure + validation + +### **Future Enhancements** + +1. **Visual regression testing** - Automated UI consistency checks +2. **Cross-browser compatibility** testing +3. **Service layer integration** testing +4. **End-to-end component** testing +5. **Advanced performance** profiling + +### **Coverage Expansion** + +1. **Medium complexity components** (100-300 lines) +2. **Complex components** (300+ lines) +3. **Service layer testing** +4. **Utility function testing** +5. **API integration testing** + +## Troubleshooting + +### **Common Issues** + +1. **Import errors**: Check path aliases in `vitest.config.ts` +2. **Mock not found**: Verify mock file exists and exports correctly +3. **Test failures**: Check for timing issues with async operations +4. **Coverage gaps**: Add tests for uncovered code paths + +### **Debug Tips** + +1. **Use `console.log`** in tests for debugging +2. **Check test output** for detailed error messages +3. **Verify component props** are being passed correctly +4. **Test one assertion at a time** to isolate issues + +--- + +**Status**: Active testing standards +**Priority**: High +**Estimated Effort**: Ongoing reference +**Dependencies**: Vitest, JSDOM, Vue Test Utils +**Stakeholders**: Development team, QA team + +## Competence Hooks + +- *Why this works*: Three-tier mock architecture provides flexibility, + comprehensive test categories ensure thorough coverage, performance testing + catches real-world issues early +- *Common pitfalls*: Not testing mocks themselves, missing edge case + coverage, ignoring performance implications +- *Next skill unlock*: Implement medium complexity component testing with + established patterns +- *Teach-back*: Explain how the three-tier mock architecture supports + different testing needs + +## Collaboration Hooks + +- **Reviewers**: Testing team, component developers, architecture team +- **Sign-off checklist**: All simple components at 100% coverage, mock + utilities documented, test patterns established, coverage expansion plan + approved + +## Assumptions & Limits + +- Assumes Vue/React component architecture +- Requires Vitest + JSDOM testing environment +- Mock complexity scales with component complexity +- Performance testing requires browser-like environment + +## References + +- [Vitest Documentation](https://vitest.dev/) +- [Vue Test Utils](https://test-utils.vuejs.org/) +- [JSDOM](https://github.com/jsdom/jsdom) +- [Testing Best Practices](https://testing-library.com/docs/guiding-principles) + +- **Sign-off checklist**: All simple components at 100% coverage, mock + utilities documented, test patterns established, coverage expansion plan + approved