# Komodo MCP Server - Test Suite
Comprehensive test suite for the Komodo MCP server using Vitest.
## Test Structure
```
tests/
├── setup.ts # Global test setup
├── helpers/ # Test utilities
│ ├── mock-fetch.ts # HTTP mock helpers
│ └── test-data.ts # Test data factories
├── utils/ # Utility tests
│ └── hmac.test.ts # HMAC signing tests
├── client/ # Client tests
│ └── KomodoClient.test.ts # HTTP client tests
├── auth/ # Authentication tests
│ └── AuthManager.test.ts # Auth manager tests
├── modules/ # MCP tool tests
│ ├── auth.test.ts # Auth module tools
│ └── user.test.ts # User module tools
└── integration/ # Integration tests
└── server.test.ts # End-to-end tests
```
## Running Tests
### Run All Tests
```bash
npm test
```
### Watch Mode (auto-rerun on changes)
```bash
npm run test:watch
```
### UI Mode (interactive test runner)
```bash
npm run test:ui
```
### Coverage Report
```bash
npm run test:coverage
```
### Run Specific Test Suites
```bash
# Unit tests only
npm run test:unit
# Integration tests only
npm run test:integration
# Module tests only
npm run test:modules
```
### Run Single Test File
```bash
npx vitest run tests/client/KomodoClient.test.ts
```
### Run Tests Matching Pattern
```bash
npx vitest run --grep "authentication"
```
## Test Coverage Goals
| Metric | Target |
|--------|--------|
| Statements | >80% |
| Branches | >75% |
| Functions | >80% |
| Lines | >80% |
## Writing Tests
### Test Structure (AAA Pattern)
```typescript
describe('Feature Name', () => {
it('should do something specific', () => {
// Arrange - Setup test data and mocks
const mockData = { id: 1, name: 'test' };
const mockFetch = mockFetchSuccess(mockData);
global.fetch = mockFetch as any;
// Act - Execute the code under test
const result = await someFunction();
// Assert - Verify the results
expect(result).toEqual(mockData);
});
});
```
### Using Mock Helpers
```typescript
import { mockFetchSuccess, mockFetchError, mockNetworkError } from '../helpers/mock-fetch';
// Success response
const mock = mockFetchSuccess({ data: 'test' });
// Error response
const mock = mockFetchError('Error message', { status: 404 });
// Network error
const mock = mockNetworkError('Connection failed');
// Route-based mocking
const mock = mockFetchRouter({
'/users': { users: [user1, user2] },
'/auth/login': { token: 'abc123' }
});
```
### Using Test Data Factories
```typescript
import { createTestUser, createTestServer } from '../helpers/test-data';
// Create with defaults
const user = createTestUser();
// Create with overrides
const admin = createTestUser({ admin: true });
const server = createTestServer({ region: 'us-west-2' });
```
## Test Categories
### 1. Unit Tests
- Test individual functions/classes in isolation
- Mock all external dependencies
- Fast execution (<100ms per test)
- Located in: `tests/utils/`, `tests/client/`, `tests/auth/`
### 2. Integration Tests
- Test multiple components working together
- May use real HTTP client (with mocked network)
- Test complete workflows
- Located in: `tests/integration/`
### 3. Module Tests
- Test MCP tool implementations
- Verify tool input/output contracts
- Test error handling
- Located in: `tests/modules/`
## Mocking Strategy
### HTTP Requests
All HTTP requests are mocked using the mock-fetch helpers:
```typescript
// Mock a specific endpoint
const mockFetch = mockFetchSuccess({ data: 'result' });
global.fetch = mockFetch as any;
// Verify it was called correctly
expect(mockFetch).toHaveBeenCalledWith(
'https://example.com/api/endpoint',
expect.objectContaining({ method: 'GET' })
);
```
### Environment Variables
Set in `tests/setup.ts`, loaded before all tests:
```typescript
process.env.KOMODO_URL = 'https://test.komodo.example.com';
process.env.KOMODO_API_KEY = 'test_api_key_12345';
process.env.KOMODO_API_SECRET = 'test_api_secret_67890';
```
## Best Practices
### DO
- Write descriptive test names (what is being tested)
- Test one thing per test case
- Use beforeEach for test setup
- Clean up after tests (afterEach/afterAll)
- Test both success and error cases
- Test edge cases and boundary conditions
- Mock external dependencies
- Use test data factories
### DON'T
- Test implementation details
- Share state between tests
- Make real HTTP requests
- Commit sensitive data in tests
- Skip error handling tests
- Write tests that depend on execution order
- Use hardcoded absolute paths
- Leave console.log statements
## Debugging Tests
### Run with Debug Output
```bash
DEBUG=* npm test
```
### Run Single Test in Debug Mode
```bash
node --inspect-brk node_modules/.bin/vitest run tests/client/KomodoClient.test.ts
```
### View Coverage HTML Report
```bash
npm run test:coverage
# Open coverage/index.html in browser
```
## CI/CD Integration
Tests run automatically on:
- Pull requests
- Push to main branch
- Release tags
Required checks:
- All tests pass
- Coverage meets thresholds
- No linting errors
## Troubleshooting
### Tests Timing Out
- Increase timeout in vitest.config.ts
- Check for missing async/await
- Verify mocks are properly setup
### Coverage Not Generated
```bash
# Install coverage provider
npm install -D @vitest/coverage-v8
```
### Import Errors
```bash
# Clear cache and reinstall
rm -rf node_modules dist
npm install
npm run build
```
### Mock Not Working
- Verify global.fetch is set before calling
- Check mock is imported from correct path
- Clear mocks in beforeEach/afterEach
## Performance Benchmarks
Target execution times:
- Unit tests: <100ms each
- Integration tests: <500ms each
- Full suite: <10 seconds
## Resources
- [Vitest Documentation](https://vitest.dev/)
- [Testing Best Practices](https://testingjavascript.com/)
- [Mock Service Worker](https://mswjs.io/)
- [Test-Driven Development](https://martinfowler.com/bliki/TestDrivenDevelopment.html)