Files
Sankofa/docs/TESTING.md

294 lines
5.5 KiB
Markdown
Raw Normal View History

# Testing Guide
**Last Updated**: 2025-01-09 for Sankofa Phoenix
## Overview
This guide covers testing strategies, test suites, and best practices for the Sankofa Phoenix platform.
## Test Structure
```
api/
src/
services/
__tests__/
*.test.ts # Unit tests for services
adapters/
__tests__/
*.test.ts # Adapter tests
schema/
__tests__/
*.test.ts # GraphQL resolver tests
src/
components/
__tests__/
*.test.tsx # Component tests
lib/
__tests__/
*.test.ts # Utility tests
blockchain/
tests/
*.test.ts # Smart contract tests
```
## Running Tests
### Frontend Tests
```bash
npm test # Run all frontend tests
npm test -- --ui # Run with Vitest UI
npm test -- --coverage # Generate coverage report
```
### Backend Tests
```bash
cd api
npm test # Run all API tests
npm test -- --coverage # Generate coverage report
```
### Blockchain Tests
```bash
cd blockchain
npm test # Run smart contract tests
```
### E2E Tests
```bash
npm run test:e2e # Run end-to-end tests
```
## Test Types
### 1. Unit Tests
Test individual functions and methods in isolation.
**Example: Resource Service Test**
```typescript
import { describe, it, expect, vi } from 'vitest'
import { getResources } from '../services/resource'
describe('getResources', () => {
it('should return resources', async () => {
const mockContext = createMockContext()
const result = await getResources(mockContext)
expect(result).toBeDefined()
})
})
```
### 2. Integration Tests
Test interactions between multiple components.
**Example: GraphQL Resolver Test**
```typescript
import { describe, it, expect } from 'vitest'
import { createTestSchema } from '../schema'
import { graphql } from 'graphql'
describe('Resource Resolvers', () => {
it('should query resources', async () => {
const query = `
query {
resources {
id
name
}
}
`
const result = await graphql(createTestSchema(), query)
expect(result.data).toBeDefined()
})
})
```
### 3. Component Tests
Test React components in isolation.
**Example: ResourceList Component Test**
```typescript
import { render, screen } from '@testing-library/react'
import { ResourceList } from '../ResourceList'
describe('ResourceList', () => {
it('should render resources', async () => {
render(<ResourceList />)
await waitFor(() => {
expect(screen.getByText('Test Resource')).toBeInTheDocument()
})
})
})
```
### 4. E2E Tests
Test complete user workflows.
**Example: Resource Provisioning E2E**
```typescript
import { test, expect } from '@playwright/test'
test('should provision resource', async ({ page }) => {
await page.goto('/resources')
await page.click('text=Provision Resource')
await page.fill('[name="name"]', 'test-resource')
await page.selectOption('[name="type"]', 'VM')
await page.click('text=Create')
await expect(page.locator('text=test-resource')).toBeVisible()
})
```
## Test Coverage Goals
- **Unit Tests**: >80% coverage
- **Integration Tests**: >60% coverage
- **Component Tests**: >70% coverage
- **E2E Tests**: Critical user paths covered
## Mocking
### Mock Database
```typescript
const mockDb = {
query: vi.fn().mockResolvedValue({ rows: [] }),
}
```
### Mock GraphQL Client
```typescript
vi.mock('@/lib/graphql/client', () => ({
apolloClient: {
query: vi.fn(),
mutate: vi.fn(),
},
}))
```
### Mock Provider APIs
```typescript
global.fetch = vi.fn().mockResolvedValue({
ok: true,
json: async () => ({ data: [] }),
})
```
## Test Utilities
### Test Helpers
```typescript
// test-utils.tsx
export function createMockContext(): Context {
return {
db: createMockDb(),
user: {
id: 'test-user',
email: 'test@sankofa.nexus',
name: 'Test User',
role: 'ADMIN',
},
}
}
```
### Test Data Factories
```typescript
export function createMockResource(overrides = {}) {
return {
id: 'resource-1',
name: 'Test Resource',
type: 'VM',
status: 'RUNNING',
...overrides,
}
}
```
## CI/CD Integration
Tests run automatically on:
- **Pull Requests**: All test suites
- **Main Branch**: All tests + coverage reports
- **Releases**: Full test suite + E2E tests
## Best Practices
1. **Write tests before fixing bugs** (TDD approach)
2. **Test edge cases and error conditions**
3. **Keep tests independent and isolated**
4. **Use descriptive test names**
5. **Mock external dependencies**
6. **Clean up after tests**
7. **Maintain test coverage**
## Performance Testing
### Load Testing
```bash
# Use k6 for load testing
k6 run tests/load/api-load-test.js
```
### Stress Testing
```bash
# Test API under load
artillery run tests/stress/api-stress.yml
```
## Security Testing
- **Dependency scanning**: `npm audit`
- **SAST**: SonarQube analysis
- **DAST**: OWASP ZAP scans
- **Penetration testing**: Quarterly assessments
## Test Reports
Test reports are generated in:
- `coverage/` - Coverage reports
- `test-results/` - Test execution results
- `playwright-report/` - E2E test reports
## Troubleshooting Tests
### Tests Timing Out
- Check for unclosed connections
- Verify mocks are properly reset
- Increase timeout values if needed
### Flaky Tests
- Ensure tests are deterministic
- Fix race conditions
- Use proper wait conditions
### Database Test Issues
- Ensure test database is isolated
- Clean up test data after each test
- Use transactions for isolation