Skip to main content

๐Ÿงช Testing Guide

This guide covers testing practices and requirements for contributing to use-typewriter-animation.

๐Ÿš€ Quick Startโ€‹

Running Testsโ€‹

bun test              # Run all tests
bun test --watch # Watch mode for development
bun test --coverage # Run with coverage report
bun test --ui # Visual test interface

Current Statusโ€‹

โœ… 228 tests passing with 100% reliability across all environments

๐ŸŽฏ Testing Philosophyโ€‹

Our testing focuses on:

  • Structural validation - Module exports, API surface, and type safety
  • Reliability - Consistent results across environments
  • Speed - Fast execution without heavy DOM dependencies
  • Maintainability - Simple, focused tests that are easy to understand

๐Ÿ“ Test Typesโ€‹

1. Module Structure Testsโ€‹

Test exports and basic functionality:

import { describe, it, expect } from 'vitest';
import { useTypewriter } from '../src';

describe('useTypewriter', () => {
it('should export the hook function', () => {
expect(typeof useTypewriter).toBe('function');
});

it('should follow React hook naming convention', () => {
expect(useTypewriter.name).toBe('useTypewriter');
});
});

2. API Surface Testsโ€‹

Validate public interface:

describe('API Surface', () => {
it('should return expected object structure', () => {
const result = useTypewriter();
expect(typeof result).toBe('object');
expect(result).toHaveProperty('typewriter');
expect(result).toHaveProperty('elements');
});
});

3. TypeScript Testsโ€‹

Ensure type safety:

describe('TypeScript Integration', () => {
it('should compile without type errors', () => {
// Test passes if TypeScript compilation succeeds
expect(typeof useTypewriter).toBe('function');
});
});

๐Ÿ”ง Test Configurationโ€‹

Vitest Config (vitest.config.ts)โ€‹

export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: ['./tests/setup.ts'],
coverage: {
provider: 'v8',
reporter: ['text', 'html'],
exclude: ['node_modules/', 'tests/', 'dist/'],
},
},
});

Test Setup (tests/setup.ts)โ€‹

import '@testing-library/jest-dom';

// Mock matchMedia for browser API tests
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: vi.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: vi.fn(),
removeListener: vi.fn(),
})),
});

โœ๏ธ Writing Testsโ€‹

Test Structureโ€‹

Use Arrange-Act-Assert pattern:

describe('Feature Name', () => {
it('should behave as expected', () => {
// Arrange
const input = 'test input';

// Act
const result = functionUnderTest(input);

// Assert
expect(result).toBe('expected output');
});
});

Test Namingโ€‹

Use descriptive names:

// โŒ Bad
it('should work', () => {});

// โœ… Good
it('should export useTypewriter hook function', () => {});
it('should handle configuration options gracefully', () => {});
it('should maintain stable API surface', () => {});

Focus Areasโ€‹

Test these key areas:

  • Exports - All public functions and types
  • Hook signatures - React hook conventions
  • Configuration - Options handling
  • Type safety - TypeScript compliance
  • Error handling - Graceful failure modes

๐Ÿ“Š Coverage Strategyโ€‹

What We Testโ€‹

  • Function exports - All public APIs
  • Type definitions - TypeScript types
  • API stability - Interface consistency
  • Error handling - Invalid inputs

Coverage Commandsโ€‹

bun test --coverage        # Generate coverage report
open coverage/index.html # View HTML report

Coverage Targetsโ€‹

  • Functions: 80%+ covered
  • Branches: 70%+ covered
  • Public API: 100% tested

๐Ÿ” Debugging Testsโ€‹

Common Issuesโ€‹

  1. Import errors - Check module resolution
  2. Type errors - Run bun run types
  3. Environment issues - Check test setup

Debug Commandsโ€‹

bun test --reporter=verbose    # Detailed output
bun test SpecificTest.test.tsx # Run specific test

Debug Exampleโ€‹

describe('Debug Test', () => {
it('should help debug issues', () => {
console.log('Debug info:', { useTypewriter });
expect(useTypewriter).toBeDefined();
});
});

๐ŸŽฏ Best Practicesโ€‹

Do's โœ…โ€‹

  • Test behavior, not implementation
  • Use descriptive test names
  • Keep tests focused and simple
  • Test error conditions
  • Validate TypeScript types

Don'ts โŒโ€‹

  • Don't test internal implementation details
  • Don't write overly complex tests
  • Don't ignore failing tests
  • Don't test everything just for coverage

Example Test Structureโ€‹

describe('useTypewriter', () => {
describe('exports', () => {
it('should export hook function', () => {
expect(typeof useTypewriter).toBe('function');
});
});

describe('API surface', () => {
it('should return expected structure', () => {
const result = useTypewriter();
expect(result).toHaveProperty('typewriter');
});
});

describe('error handling', () => {
it('should handle invalid config gracefully', () => {
expect(() => useTypewriter({ speed: -1 })).not.toThrow();
});
});
});

๐Ÿš€ Adding Tests for New Featuresโ€‹

When adding new features:

  1. Test exports - Ensure new functions are exported
  2. Test API - Validate interface and return types
  3. Test integration - Ensure it works with existing features
  4. Test edge cases - Handle invalid inputs gracefully

New Feature Test Templateโ€‹

describe('NewFeature', () => {
it('should export new feature function', () => {
expect(typeof newFeature).toBe('function');
});

it('should integrate with existing API', () => {
const result = useTypewriter({ newOption: true });
expect(result).toBeDefined();
});
});

โœ… Pre-Commit Checklistโ€‹

Before submitting your PR:

  • All tests pass: bun test
  • New features have tests
  • TypeScript types are tested
  • Coverage requirements met
  • No console errors or warnings

Need help with testing? Open an issue or discussion on GitHub!

Remember: Good tests make the library reliable and maintainable for everyone. ๐ŸŽฏ