Skip to main content

๐Ÿงช Testing Guide - MCP ADR Analysis Server

Confidence: 95% - Comprehensive guide based on analysis of existing testing infrastructure

๐Ÿ“‹ Table of Contentsโ€‹


๐Ÿš€ Quick Startโ€‹

Prerequisitesโ€‹

  • Node.js: โ‰ฅ20.0.0
  • npm: โ‰ฅ9.0.0
  • Memory: โ‰ฅ1GB available RAM
  • Disk: โ‰ฅ1GB free space

Installation & Setupโ€‹

# Install dependencies
npm install

# Run all tests
npm test

# Run tests with coverage
npm run test:coverage

# Run tests in watch mode
npm run test:watch

Verify Installationโ€‹

# Quick smoke test
npm run test tests/smoke.test.ts

# Test infrastructure health
./scripts/test-infrastructure.sh validate

๐Ÿ—๏ธ Testing Architectureโ€‹

Core Componentsโ€‹

tests/
โ”œโ”€โ”€ __mocks__/ # Mock implementations for external dependencies
โ”œโ”€โ”€ integration/ # Cross-component integration tests
โ”œโ”€โ”€ performance/ # Performance and load tests
โ”œโ”€โ”€ tools/ # Individual tool unit tests
โ”œโ”€โ”€ utils/ # Utility function tests
โ”œโ”€โ”€ setup.ts # Global test configuration
โ””โ”€โ”€ README.md # Testing documentation

Key Technologiesโ€‹

  • Jest: Primary testing framework with TypeScript support
  • ts-jest: TypeScript transformation and ESM support
  • Tree-sitter Mocks: Native module mocking for cross-platform compatibility
  • Custom Matchers: Domain-specific assertions for ADR validation

Test Infrastructure Featuresโ€‹

  • โœ… Resource Monitoring: Memory and file handle tracking
  • โœ… Automatic Cleanup: Temp directory and mock cleanup
  • โœ… Coverage Thresholds: 85% minimum coverage requirement
  • โœ… Performance Tracking: Memory usage and execution time monitoring
  • โœ… CI/CD Integration: JUnit XML reporting for CI systems

๐ŸŽฏ Test Types & Categoriesโ€‹

1. Unit Tests (tests/tools/, tests/utils/)โ€‹

Purpose: Test individual functions and classes in isolation

// Example: Tool unit test
describe('ADRValidationTool', () => {
it('should validate ADR structure', async () => {
const result = await adrValidationTool.validate(mockAdr);
expect(result).toBeValidAdr();
});
});

Coverage: Functions, classes, utilities, and individual tools

2. Integration Tests (tests/integration/)โ€‹

Purpose: Test component interactions and workflows

// Example: Memory system integration
describe('Memory System Integration', () => {
it('should handle complex workflow chains', async () => {
const workflow = await orchestrator.executeChain(steps);
expect(workflow.success).toBe(true);
});
});

Coverage: Tool chains, memory systems, MCP protocol interactions

3. Performance Tests (tests/performance/)โ€‹

Purpose: Validate performance characteristics and resource usage

// Example: Memory performance test
describe('Memory Performance', () => {
it('should handle large datasets efficiently', async () => {
const result = await processLargeDataset(testData);
expect(result).toShowSignificantImprovement(0.1);
});
});

Coverage: Memory usage, execution time, resource efficiency

4. End-to-End Tests (scripts/test-mcp-*.sh)โ€‹

Purpose: Test complete MCP server functionality

# MCP server integration test
./scripts/test-mcp-server.sh

# MCP functionality validation
./scripts/test-mcp-functionality.sh

๐Ÿƒโ€โ™‚๏ธ Running Testsโ€‹

Basic Commandsโ€‹

# All tests (recommended)
npm test

# Specific test categories
npm run test:unit # Unit tests only
npm run test:integration # Integration tests only
npm run test:performance # Performance tests only

# Advanced testing
npm run test:advanced # Advanced prompting tests
npm run test:quality # Code quality validation
npm run test:infrastructure # Infrastructure tests

Test Infrastructure Scriptโ€‹

# Comprehensive test runner with resource monitoring
./scripts/test-infrastructure.sh [TYPE] [OPTIONS]

# Examples:
./scripts/test-infrastructure.sh unit
./scripts/test-infrastructure.sh integration --verbose
./scripts/test-infrastructure.sh performance --timeout=600
./scripts/test-infrastructure.sh cleanup # Clean up test artifacts

Coverage & Reportingโ€‹

# Generate coverage report
npm run test:coverage

# View coverage in browser
open coverage/lcov-report/index.html

# CI-friendly JUnit output
npm test -- --ci --reporters=jest-junit

Watch Mode Developmentโ€‹

# Watch for changes and re-run tests
npm run test:watch

# Watch specific test pattern
npm run test:watch -- --testPathPattern=tools

โœ๏ธ Writing Testsโ€‹

Test File Structureโ€‹

/**
* @fileoverview Tests for [Component Name]
* @category [Unit|Integration|Performance]
*/

import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
import { testInfrastructure } from '../utils/test-infrastructure.js';
import { ComponentUnderTest } from '../../src/path/to/component.js';

describe('ComponentUnderTest', () => {
let component: ComponentUnderTest;
let testContext: any;

beforeEach(async () => {
testContext = await testInfrastructure.createTestContext();
component = new ComponentUnderTest(testContext.config);
});

afterEach(async () => {
await testInfrastructure.cleanupTestContext(testContext);
});

describe('core functionality', () => {
it('should perform expected behavior', async () => {
// Arrange
const input = testContext.createMockInput();

// Act
const result = await component.process(input);

// Assert
expect(result).toBeDefined();
expect(result.success).toBe(true);
});
});
});

Custom Matchersโ€‹

The testing framework includes custom Jest matchers for domain-specific assertions:

// ADR validation
expect(adrObject).toBeValidAdr();

// Schema validation
expect(dataObject).toHaveValidSchema();

// Prompt validation
expect(promptObject).toBeValidPromptObject();

// Performance improvement validation
expect(performanceResult).toShowSignificantImprovement(0.15);

Mock Usageโ€‹

// Tree-sitter mocks (automatically available)
import TreeSitter from 'tree-sitter'; // Uses mock implementation

// Custom mocks
import { mockFileSystem } from '../__mocks__/file-system.js';

beforeEach(() => {
mockFileSystem.reset();
mockFileSystem.addFile('/test/path', 'content');
});

Test Data Managementโ€‹

// Use test infrastructure for consistent test data
const testData = testInfrastructure.generateTestData({
type: 'adr',
count: 5,
complexity: 'medium'
});

// Create temporary directories
const tempDir = await testInfrastructure.createTempDirectory();

๐ŸŽฏ Testing Best Practicesโ€‹

1. Test Organizationโ€‹

  • Group related tests using describe blocks
  • Use descriptive test names that explain the expected behavior
  • Follow AAA pattern: Arrange, Act, Assert

2. Resource Managementโ€‹

// โœ… Good: Proper cleanup
afterEach(async () => {
await testInfrastructure.cleanupTestContext(testContext);
});

// โŒ Bad: No cleanup
afterEach(() => {
// Missing cleanup
});

3. Async Testingโ€‹

// โœ… Good: Proper async handling
it('should handle async operations', async () => {
const result = await asyncOperation();
expect(result).toBeDefined();
});

// โŒ Bad: Missing await
it('should handle async operations', () => {
const result = asyncOperation(); // Missing await
expect(result).toBeDefined();
});

4. Test Isolationโ€‹

// โœ… Good: Independent tests
beforeEach(() => {
component = new Component(freshConfig);
});

// โŒ Bad: Shared state
const component = new Component(config); // Shared across tests

5. Performance Considerationsโ€‹

// โœ… Good: Performance-aware testing
it('should complete within reasonable time', async () => {
const startTime = Date.now();
await heavyOperation();
const duration = Date.now() - startTime;
expect(duration).toBeLessThan(5000); // 5 seconds
});

๐Ÿ”ง Troubleshootingโ€‹

Common Issuesโ€‹

1. Memory Issuesโ€‹

Problem: Tests fail with out-of-memory errors

Solution:

# Increase Node.js memory limit
export NODE_OPTIONS="--max-old-space-size=4096"
npm test

2. Tree-sitter Native Module Issuesโ€‹

Problem: Tree-sitter modules fail to load in test environment

Solution: The project includes comprehensive mocks in tests/__mocks__/ that automatically handle this.

3. Timeout Issuesโ€‹

Problem: Tests timeout in CI environment

Solution:

# Use infrastructure script with custom timeout
./scripts/test-infrastructure.sh integration --timeout=600

4. Resource Leaksโ€‹

Problem: Tests leave temporary files or handles open

Solution:

# Run cleanup
./scripts/test-infrastructure.sh cleanup

# Check resource status
npm test -- --verbose

Debug Modeโ€‹

# Enable debug logging
DEBUG=mcp-adr:* npm test

# Run single test with full output
npm test -- --testNamePattern="specific test" --verbose

Performance Debuggingโ€‹

# Run with memory profiling
node --inspect-brk node_modules/.bin/jest --runInBand

# Performance test analysis
npm run test:performance -- --verbose

๐Ÿš€ CI/CD Integrationโ€‹

GitHub Actions Configurationโ€‹

The project includes automated testing in CI with:

  • Multiple Node.js versions (20.x, 22.x)
  • Cross-platform testing (Ubuntu, macOS, Windows)
  • Coverage reporting with threshold enforcement
  • Performance regression detection

Local CI Simulationโ€‹

# Simulate CI environment
CI=true npm test

# Generate CI-compatible reports
npm test -- --ci --coverage --reporters=jest-junit

Pre-commit Testingโ€‹

# Run pre-commit checks
npm run lint
npm run typecheck
npm test

# Or use the pre-commit script
./scripts/pre-commit-check.sh

๐Ÿ“Š Coverage Requirementsโ€‹

The project maintains 85% minimum coverage across:

  • Branches: 85%
  • Functions: 85%
  • Lines: 85%
  • Statements: 85%

Coverage Exclusionsโ€‹

  • Type definition files (*.d.ts)
  • Test files (*.test.ts)
  • Mock implementations
  • Performance test utilities

Viewing Coverageโ€‹

# Generate and view coverage
npm run test:coverage
open coverage/lcov-report/index.html

๐Ÿค Contributing Testsโ€‹

Before Submittingโ€‹

  1. Run full test suite: npm test
  2. Check coverage: npm run test:coverage
  3. Validate performance: npm run test:performance
  4. Run linting: npm run lint

Test Contribution Guidelinesโ€‹

  1. Write tests for new features - All new functionality must include tests
  2. Maintain coverage thresholds - Don't reduce overall coverage
  3. Use existing patterns - Follow established testing patterns
  4. Document complex tests - Add comments for non-obvious test logic
  5. Test edge cases - Include boundary conditions and error scenarios

Review Checklistโ€‹

  • Tests follow naming conventions
  • Proper async/await usage
  • Resource cleanup implemented
  • Custom matchers used appropriately
  • Performance considerations addressed
  • Documentation updated if needed

๐Ÿ“š Additional Resourcesโ€‹


Need Help?


This guide is maintained as part of the MCP ADR Analysis Server project. Last updated: October 2025