Skip to content

MVP Testing Strategy

Garot Conklin edited this page Jan 17, 2025 · 1 revision

MVP Testing Strategy

Testing Overview

The testing strategy for Cursor Rules Dynamic follows a comprehensive approach to ensure reliability and maintainability. Our testing pyramid consists of:

  1. Unit Tests
  2. Integration Tests
  3. End-to-End Tests
  4. Performance Tests

Test Coverage Goals

  • Overall Coverage: 100%
  • Critical Paths: 100%
  • Edge Cases: 100%
  • Error Handling: 100%

Testing Levels

1. Unit Testing

Core Components

  • TextConverter
  • TemplateService
  • ProjectAnalyzer
  • RuleValidator

Test Examples

suite('TextConverter Test Suite', () => {
    let testFilePath: string;
    let testFileUri: vscode.Uri;

    setup(async () => {
        const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
        assert.ok(workspaceFolder, 'No workspace folder found');
        
        testFilePath = path.join(workspaceFolder.uri.fsPath, '.cursorrules.test');
        testFileUri = vscode.Uri.file(testFilePath);
        
        await fs.promises.writeFile(testFilePath, 'Test content');
    });

    teardown(async () => {
        try {
            await fs.promises.unlink(testFilePath);
        } catch (e) {
            // Ignore errors if file doesn't exist
        }
    });

    test('should convert text to JSON format', async () => {
        const result = await TextConverter.convertToJson('Test content');
        assert.ok(result.languages.default, 'Should have default rules');
    });
});

2. Integration Testing

Test Scenarios

  • Command Registration
  • File System Operations
  • Template Management
  • Rule Processing

Test Examples

suite('Extension Integration Test Suite', () => {
    test('Extension activation should register all commands', async () => {
        const commands = await vscode.commands.getCommands();
        
        const requiredCommands = [
            'cursor-rules-dynamic.showStatus',
            'cursor-rules-dynamic.convertToJson',
            'cursor-rules-dynamic.browseTemplates',
            'cursor-rules-dynamic.scanProject'
        ];
        
        requiredCommands.forEach(cmd => {
            assert.ok(
                commands.includes(cmd),
                `Command ${cmd} should be registered`
            );
        });
    });
});

3. End-to-End Testing

Test Scenarios

  • Complete Workflows
  • User Interactions
  • Error Scenarios
  • Recovery Paths

Test Examples

suite('End-to-End Test Suite', () => {
    test('should complete full conversion workflow', async () => {
        // Create test file
        const content = 'Test rule content';
        await createTestFile(content);
        
        // Execute conversion
        await vscode.commands.executeCommand(
            'cursor-rules-dynamic.convertToJson',
            testFileUri
        );
        
        // Verify result
        const result = await vscode.workspace.fs.readFile(testFileUri);
        const json = JSON.parse(result.toString());
        assert.ok(json.languages.default.rules[0].description === content);
    });
});

4. Performance Testing

Test Scenarios

  • Large File Handling
  • Multiple File Processing
  • Memory Usage
  • Response Times

Test Examples

suite('Performance Test Suite', () => {
    test('should handle large files efficiently', async () => {
        const largeContent = 'x'.repeat(1000000);
        const startTime = process.hrtime();
        
        await TextConverter.convertToJson(largeContent);
        
        const [seconds, nanoseconds] = process.hrtime(startTime);
        assert.ok(
            seconds * 1000 + nanoseconds / 1000000 < 1000,
            'Should process within 1 second'
        );
    });
});

Test Infrastructure

1. Test Runner Setup

export async function run(): Promise<void> {
    const mocha = new Mocha({
        ui: 'tdd',
        color: true,
        timeout: 60000
    });

    const testsRoot = path.resolve(__dirname, './');
    
    try {
        const files = await glob('**/**.test.js', { cwd: testsRoot });
        files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));

        return new Promise<void>((resolve, reject) => {
            mocha.run(failures => {
                failures ? reject(new Error(`${failures} tests failed`)) : resolve();
            });
        });
    } catch (err) {
        console.error('Error loading test files:', err);
        throw err;
    }
}

2. Coverage Reporting

{
    "scripts": {
        "test:coverage": "c8 --reporter=lcov --reporter=text-summary npm run test"
    }
}

Testing Guidelines

1. Test Organization

  • Group related tests
  • Clear test names
  • Proper setup/teardown
  • Isolated test cases

2. Test Quality

  • Test one thing at a time
  • Clear assertions
  • Meaningful error messages
  • Proper cleanup

3. Test Maintenance

  • Regular updates
  • Coverage monitoring
  • Performance tracking
  • Documentation updates

Continuous Integration

1. GitHub Actions

name: Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v2
      - run: npm ci
      - run: npm test
      - run: npm run test:coverage

2. Quality Gates

  • All tests passing
  • Coverage thresholds met
  • Performance benchmarks met
  • No security issues

Test Documentation

1. Test Cases

  • Purpose
  • Prerequisites
  • Steps
  • Expected results

2. Test Results

  • Coverage reports
  • Performance metrics
  • Error logs
  • Test history

Future Improvements

1. Test Automation

  • More E2E tests
  • Visual regression tests
  • Load testing
  • Security testing

2. Test Tools

  • Better reporting
  • Automated reviews
  • Performance profiling
  • Coverage analysis