Testing

Testing Strategy

ReCloud implements comprehensive testing across all layers with automated CI/CD pipelines ensuring quality and reliability.

Test Types

Unit Tests

Component Testing

// ToolDispatcher unit test
import { ToolDispatcher } from '../services/ToolDispatcher';
import { expect } from 'chai';
import sinon from 'sinon';

describe('ToolDispatcher', () => {
  let dispatcher: ToolDispatcher;
  let mockApiClient: sinon.SinonStubbedInstance<ApiClient>;

  beforeEach(() => {
    mockApiClient = sinon.createStubInstance(ApiClient);
    dispatcher = new ToolDispatcher(mockApiClient);
  });

  describe('dispatch', () => {
    it('should route remote tools to API client', async () => {
      const toolName = 'analyzeSentiment';
      const parameters = { text: 'test' };

      mockApiClient.executeTool.resolves({ success: true });

      const result = await dispatcher.dispatch(toolName, parameters);

      expect(mockApiClient.executeTool.calledWith(toolName, parameters)).to.be.true;
      expect(result.success).to.be.true;
    });
  });
});

Utility Function Testing

// Configuration utility tests
describe('getModelForTool', () => {
  afterEach(() => {
    delete process.env.ANALYZE_SENTIMENT_MODEL;
  });

  it('returns default model for unmapped tool', () => {
    expect(getModelForTool('unknown')).to.equal('gemini-2.5-flash');
  });

  it('returns mapped model from environment', () => {
    process.env.ANALYZE_SENTIMENT_MODEL = 'gemini-2.5-pro';
    expect(getModelForTool('analyzeSentiment')).to.equal('gemini-2.5-pro');
  });
});

Integration Tests

API Integration

// API endpoint integration test
describe('Tool Execution API', () => {
  let app: Express;
  let server: Server;

  beforeAll(async () => {
    app = await createApp();
    server = app.listen(3001);
  });

  afterAll(async () => {
    await server.close();
  });

  it('executes tool successfully', async () => {
    const response = await request(app)
      .post('/tools/execute')
      .set('Authorization', 'Bearer test-key')
      .send({
        toolName: 'analyzeSentiment',
        parameters: { text: 'Great product!' }
      });

    expect(response.status).toBe(200);
    expect(response.body.success).toBe(true);
    expect(response.body.result).toHaveProperty('sentiment');
  });
});

Database Integration

// Database integration test
describe('Tool Execution Repository', () => {
  let repository: ToolExecutionRepository;
  let db: Database;

  beforeEach(async () => {
    db = await createTestDatabase();
    repository = new ToolExecutionRepository(db);
  });

  afterEach(async () => {
    await db.destroy();
  });

  it('saves tool execution', async () => {
    const execution = {
      toolName: 'analyzeSentiment',
      parameters: { text: 'test' },
      result: { sentiment: 'positive' },
      duration: 1000
    };

    const saved = await repository.save(execution);
    expect(saved.id).toBeDefined();

    const retrieved = await repository.findById(saved.id);
    expect(retrieved.toolName).toEqual('analyzeSentiment');
  });
});

End-to-End Tests

MCP Protocol Testing

// MCP server E2E test
describe('MCP Server E2E', () => {
  let mcpClient: MCPClient;
  let server: Server;

  beforeAll(async () => {
    // Start MCP server
    server = await startTestServer();

    // Connect MCP client
    mcpClient = new MCPClient();
    await mcpClient.connect('http://localhost:3002');
  });

  afterAll(async () => {
    await mcpClient.disconnect();
    await server.close();
  });

  it('executes tool via MCP protocol', async () => {
    const result = await mcpClient.callTool('recloud', {
      subcommand: 'analyzeSentiment',
      parameters: { text: 'Amazing!' }
    });

    expect(result.success).toBe(true);
    expect(result.data.sentiment).toBeDefined();
  });
});

Full Workflow Testing

// Complete workflow E2E test
describe('Complete ReCloud Workflow', () => {
  it('processes request from TrayApp through MCP to API', async () => {
    // 1. Start all services
    await startAllServices();

    // 2. Simulate TrayApp request
    const trayApp = new TrayAppSimulator();
    await trayApp.sendToolRequest('analyzeSentiment', { text: 'test' });

    // 3. Verify MCP server received request
    const mcpLogs = await getMcpLogs();
    expect(mcpLogs).toContain('analyzeSentiment');

    // 4. Verify API processed request
    const apiLogs = await getApiLogs();
    expect(apiLogs).toContain('tool execution completed');

    // 5. Verify result returned to TrayApp
    const result = await trayApp.getLastResult();
    expect(result.success).toBe(true);
  });
});

Quality Assurance

Testing Coverage

  • Unit Tests: Individual component validation
  • Integration Tests: Component interaction verification
  • End-to-End Tests: Complete workflow validation
  • Performance Tests: Load and stress testing

Quality Standards

  • Automated Testing: Comprehensive test suites for all components
  • Continuous Integration: Automated testing on every code change
  • Performance Validation: Load testing and performance benchmarks
  • Security Testing: Automated security scans and vulnerability checks

Performance Testing

Load Testing

Tool Execution Load Test

// Load test for tool execution
import { check } from 'k6';
import http from 'k6/http';

export let options = {
  vus: 50, // 50 virtual users
  duration: '5m',
  thresholds: {
    http_req_duration: ['p(95)<2000'], // 95% of requests < 2s
    http_req_failed: ['rate<0.05'], // Error rate < 5%
  },
};

const tools = ['analyzeSentiment', 'generateCode', 'generateQR'];
const apiKey = __ENV.API_KEY;

export default function () {
  const tool = tools[Math.floor(Math.random() * tools.length)];
  const payload = generatePayload(tool);

  const response = http.post(
    'http://localhost:3001/tools/execute',
    JSON.stringify({
      toolName: tool,
      parameters: payload
    }),
    {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${apiKey}`
      }
    }
  );

  check(response, {
    'status is 200': (r) => r.status === 200,
    'response time < 5000ms': (r) => r.timings.duration < 5000,
    'has success field': (r) => r.json().success !== undefined
  });
}

function generatePayload(tool: string) {
  switch (tool) {
    case 'analyzeSentiment':
      return { text: 'This is a great product!' };
    case 'generateCode':
      return { description: 'Create a hello world function', language: 'javascript' };
    case 'generateQR':
      return { text: 'https://recloud.dev' };
  }
}

Stress Testing

Maximum Load Testing

# Apache Bench stress test
ab -n 10000 -c 100 -T 'application/json' \
  -H 'Authorization: Bearer test-key' \
  -p payload.json \
  http://localhost:3001/tools/execute

Memory Leak Testing

// Memory leak detection test
describe('Memory Leak Tests', () => {
  it('should not leak memory during repeated tool executions', async () => {
    const initialMemory = process.memoryUsage().heapUsed;

    // Execute tool 1000 times
    for (let i = 0; i < 1000; i++) {
      await executeTool('analyzeSentiment', { text: `Test ${i}` });
    }

    const finalMemory = process.memoryUsage().heapUsed;
    const memoryIncrease = finalMemory - initialMemory;

    // Allow for some memory increase but not excessive
    expect(memoryIncrease).toBeLessThan(50 * 1024 * 1024); // 50MB
  });
});

Security Testing

Vulnerability Scanning

Dependency Scanning

# NPM audit
npm audit

# Snyk security scan
snyk test

# OWASP Dependency Check
dependency-check --scan . --format JSON

Code Security Analysis

// Security linting rules
const securityRules = {
  // Prevent dangerous functions
  'no-eval': 'error',
  'no-implied-eval': 'error',

  // Prevent XSS
  'react/jsx-no-script-url': 'error',

  // Prevent command injection
  'security/detect-child-process': 'error',
  'security/detect-non-literal-fs-filename': 'error'
};

Penetration Testing

API Security Testing

# OWASP ZAP automated scan
zap.sh -cmd -quickurl http://localhost:3001 -quickout report.html

# API fuzzing
ffuf -w wordlist.txt -u http://localhost:3001/api/FUZZ -mc 200

Authentication Testing

// Authentication bypass test
describe('Authentication Security', () => {
  it('should reject requests without valid API key', async () => {
    const response = await request(app)
      .post('/tools/execute')
      .send({ toolName: 'test' });

    expect(response.status).toBe(401);
  });

  it('should reject malformed API keys', async () => {
    const response = await request(app)
      .post('/tools/execute')
      .set('Authorization', 'Bearer invalid-key')
      .send({ toolName: 'test' });

    expect(response.status).toBe(401);
  });
});

Test Data Management

Test Database Setup

Database Fixtures

// Test data setup
export async function setupTestData() {
  await db.migrate.latest();

  // Create test users
  await db('users').insert([
    { id: 1, email: 'test@example.com', api_key: 'test-key' },
    { id: 2, email: 'admin@example.com', api_key: 'admin-key' }
  ]);

  // Create test tools
  await db('tools').insert([
    { name: 'analyzeSentiment', category: 'analysis' },
    { name: 'generateCode', category: 'generation' }
  ]);
}

export async function teardownTestData() {
  await db.migrate.rollback();
}

Continuous Testing

Test Environments

Development Testing

# Run tests in watch mode during development
npm run test:watch

# Run specific test file
npm test -- src/services/ToolDispatcher.test.ts

Staging Testing

# Full test suite for staging deployments
npm run test:ci

# Performance regression tests
npm run test:performance

Production Testing

# Smoke tests for production deployments
npm run test:smoke

# Synthetic monitoring
npm run test:synthetic

Test Reporting

Coverage Reports

// Generate coverage report
import { createCoverageMap } from 'istanbul-lib-coverage';
import { createCoverageSummary } from 'istanbul-lib-report';

const coverageMap = createCoverageMap(global.__coverage__);
const summary = createCoverageSummary(coverageMap);

console.log('Coverage Summary:');
console.log(`Statements: ${summary.statements.pct}%`);
console.log(`Branches: ${summary.branches.pct}%`);
console.log(`Functions: ${summary.functions.pct}%`);
console.log(`Lines: ${summary.lines.pct}%`);

Test Results Dashboard

// Test results aggregation
interface TestResults {
  total: number;
  passed: number;
  failed: number;
  skipped: number;
  duration: number;
  coverage: CoverageSummary;
}

const dashboard = {
  generateReport: (results: TestResults) => {
    // Generate HTML dashboard
    // Send notifications for failures
    // Update CI status
  }
};

Comprehensive testing ensures ReCloud's reliability, security, and performance across all deployment scenarios.

Slopbook® Engine - powered by Slopman