← back to Wine Finder Next
TESTING_QUICK_START.md
300 lines
# Testing Quick Start Guide
## Installation
```bash
# Install test dependencies
npm install --save-dev \
jest \
@testing-library/react \
@testing-library/jest-dom \
@testing-library/user-event \
@playwright/test \
supertest \
ts-jest \
@types/jest \
@types/supertest \
jest-environment-jsdom
```
## Quick Commands
```bash
# Run all unit tests
npm run test:unit
# Run in watch mode (recommended for development)
npm test
# Run specific test file
npm test inputValidation.test.ts
# Run with coverage
npm run test:coverage
# Run E2E tests
npm run test:e2e
# Run E2E with UI (great for debugging)
npm run test:e2e:ui
```
## Test Structure at a Glance
```
__tests__/
├── unit/ # Unit tests (70+ tests)
├── integration/ # API tests (30+ tests)
├── security/ # Security tests (50+ tests)
├── performance/ # Load tests (15+ tests)
└── fixtures/ # Test data
e2e/ # End-to-end tests (25+ tests)
```
## Writing Your First Test
### 1. Unit Test Example
```typescript
// __tests__/unit/myFunction.test.ts
describe('MyFunction', () => {
it('should do something', () => {
const result = myFunction('input');
expect(result).toBe('expected');
});
});
```
### 2. Integration Test Example
```typescript
// __tests__/integration/api-endpoint.test.ts
import { GET } from '@/app/api/endpoint/route';
import { NextRequest } from 'next/server';
describe('API Endpoint', () => {
it('should return data', async () => {
const request = new NextRequest('http://localhost:3000/api/endpoint');
const response = await GET(request);
const data = await response.json();
expect(response.status).toBe(200);
expect(data.success).toBe(true);
});
});
```
### 3. E2E Test Example
```typescript
// e2e/user-flow.spec.ts
import { test, expect } from '@playwright/test';
test('user can purchase shares', async ({ page }) => {
await page.goto('/membership');
await page.click('[data-testid="buy-btn"]');
await expect(page.locator('[data-testid="success"]')).toBeVisible();
});
```
## Test Coverage Goals
| Metric | Target | Priority |
|--------|--------|----------|
| Lines | 70% | High |
| Functions | 70% | High |
| Branches | 70% | Medium |
| Statements | 70% | Medium |
## Common Test Patterns
### Arrange-Act-Assert (AAA)
```typescript
it('should validate email', () => {
// Arrange
const email = 'test@example.com';
// Act
const result = validateEmail(email);
// Assert
expect(result).toBe(true);
});
```
### Mocking
```typescript
jest.mock('@/lib/database');
import { database } from '@/lib/database';
beforeEach(() => {
(database.query as jest.Mock).mockResolvedValue([]);
});
```
### Async Testing
```typescript
it('should fetch data', async () => {
const data = await fetchData();
expect(data).toHaveLength(5);
});
```
## Debugging Tests
### VS Code Debug Configuration
```json
{
"type": "node",
"request": "launch",
"name": "Jest Debug",
"program": "${workspaceFolder}/node_modules/.bin/jest",
"args": ["--runInBand", "--no-cache"],
"console": "integratedTerminal"
}
```
### Playwright Debug
```bash
# Open Playwright UI
npm run test:e2e:ui
# Debug mode
PWDEBUG=1 npm run test:e2e
# Run specific test
npx playwright test membership-flows.spec.ts
```
## Test Data
Use fixtures from `__tests__/fixtures/testData.ts`:
```typescript
import { mockBottles, createMockBottle } from '../fixtures/testData';
// Use existing mock
const bottle = mockBottles[0];
// Create custom mock
const customBottle = createMockBottle({ vintage: 2015 });
```
## Security Testing Checklist
- [ ] SQL Injection prevention
- [ ] XSS prevention
- [ ] CSRF protection
- [ ] Rate limiting
- [ ] Input validation
- [ ] Authentication
- [ ] Authorization
- [ ] File upload validation
- [ ] Header injection prevention
## Performance Testing Checklist
- [ ] API response time < 500ms
- [ ] Database queries < 10ms
- [ ] Memory leak detection
- [ ] Concurrent request handling
- [ ] Load testing (100+ users)
- [ ] Stress testing (burst traffic)
## E2E Testing Checklist
- [ ] Happy path flows
- [ ] Error handling
- [ ] Mobile responsiveness
- [ ] Accessibility (ARIA, keyboard nav)
- [ ] Cross-browser compatibility
- [ ] Network error handling
## CI/CD Integration
Tests automatically run on:
- Push to `main` or `develop`
- Pull requests
- Manual workflow dispatch
View results in GitHub Actions tab.
## Common Issues & Solutions
### Issue: Tests timeout
```typescript
jest.setTimeout(10000); // Increase timeout
```
### Issue: Module not found
```typescript
// Check moduleNameMapper in jest.config.js
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/$1',
}
```
### Issue: Async test fails
```typescript
// Always await async operations
await expect(asyncFn()).resolves.toBe(true);
```
### Issue: E2E test flaky
```typescript
// Use waitFor instead of waitForTimeout
await page.waitForSelector('[data-testid="element"]');
```
## Best Practices
1. **Test Naming**: Use descriptive names
- Good: `should validate email format correctly`
- Bad: `test1`
2. **Test Independence**: Each test should run independently
```typescript
beforeEach(() => {
// Reset state
});
```
3. **Don't Test Implementation**: Test behavior, not internals
```typescript
// Good
expect(result).toBe('success');
// Bad
expect(internalState.value).toBe(123);
```
4. **Keep Tests Simple**: One concept per test
5. **Use Test Data Factories**: Consistent, reusable test data
6. **Mock External Dependencies**: Don't hit real APIs
7. **Test Edge Cases**: Empty strings, null, undefined, extreme values
## Resources
- Full docs: `/TEST_SUITE_DOCUMENTATION.md`
- Test helpers: `/__tests__/helpers/testUtils.ts`
- Fixtures: `/__tests__/fixtures/testData.ts`
- CI/CD: `/.github/workflows/test-automation.yml`
## Getting Help
1. Check test documentation
2. Review existing tests for patterns
3. Check CI/CD logs for failures
4. Use `npm run test:e2e:ui` for E2E debugging
---
**Happy Testing!** 🧪