Files
api-codegen/tests/README.md

322 lines
10 KiB
Markdown
Raw Normal View History

2025-10-28 09:58:44 +03:00
# Документация по тестированию API CodeGen
## Обзор
Проект использует комплексную систему тестирования с максимальным покрытием:
- **Юнит тесты** - тестирование отдельных модулей
- **Интеграционные тесты** - тестирование взаимодействия компонентов
- **E2E тесты** - полный цикл от генерации до использования
**Общее количество тестов:** ~72 кейса
## Стек технологий
- **Bun test** - встроенный test runner (быстрый, совместим с Jest API)
- **msw** - Mock Service Worker для HTTP мокирования
- **tmp** - создание временных директорий
- **execa** - запуск CLI команд
## Структура тестов
```
tests/
├── fixtures/ # Тестовые OpenAPI спецификации
│ ├── minimal.json # Минимальная валидная спецификация
│ ├── valid.json # Полная валидная спецификация
│ ├── complex.json # Сложная (100+ endpoints)
│ ├── with-auth.json # С authentication
│ ├── invalid.json # Невалидная спецификация
│ ├── empty.json # Пустая спецификация
│ └── edge-cases.json # Unicode, спецсимволы
├── helpers/ # Вспомогательные функции
│ ├── setup.ts # Создание/очистка temp директорий
│ ├── mock-server.ts # Mock HTTP сервер
│ └── fixtures.ts # Утилиты для фикстур
├── unit/ # Юнит тесты
│ ├── cli.test.ts # CLI команды
│ ├── generator.test.ts # Генератор
│ ├── config.test.ts # Валидация конфигурации
│ └── utils/
│ └── file.test.ts # Файловые утилиты
└── integration/ # Интеграционные тесты
├── e2e-generation.test.ts # E2E генерация
└── generated-client.test.ts # Сгенерированный клиент
```
## Запуск тестов
### Все тесты
```bash
bun test
```
### Только юнит тесты
```bash
bun test:unit
```
### Только интеграционные тесты
```bash
bun test:integration
```
### Watch режим
```bash
bun test:watch
```
### С coverage
```bash
bun test:coverage
```
### Конкретный файл
```bash
bun test tests/unit/cli.test.ts
```
### Конкретный тест
```bash
bun test -t "should generate client with custom name"
```
## Покрываемые сценарии
### 1. CLI тесты (15 кейсов)
**Базовые сценарии:**
- ✅ Запуск с локальным файлом
- ✅ Запуск с URL
- ✅ Генерация с кастомным именем
- ✅ Автоматическое имя из OpenAPI title
- ✅ Отображение версии `--version`
- ✅ Отображение help `--help`
**Обработка ошибок:**
- ❌ Отсутствие `--input`
- ❌ Отсутствие `--output`
- ❌ Несуществующий файл
- ❌ Невалидный OpenAPI
- ❌ Недоступный URL
- ❌ Ошибки записи
### 2. Генератор (20 кейсов)
**Корректная генерация:**
- ✅ Создание файла
- ✅ Структура кода
-Все HTTP методы (GET, POST, PUT, PATCH, DELETE)
- ✅ Типы для request/response
- ✅ Path/query параметры
- ✅ Request body
- ✅ Enum типы
- ✅ Bearer authentication
- ✅ Хук `onFormatRouteName`
- ✅ BaseUrl из servers
**Edge cases:**
- ❌ Пустая спецификация
- ❌ Минимальная спецификация
- ❌ Сложная спецификация (100+ endpoints)
- ❌ Unicode символы
### 3. Утилиты (10 кейсов)
**file.test.ts:**
-`fileExists()` - существующий файл
-`fileExists()` - несуществующий файл
-`readJsonFile()` - локальный файл
-`readJsonFile()` - URL
-`readJsonFile()` - невалидный JSON
-`readJsonFile()` - недоступный URL
-`ensureDir()` - создание директорий
-`writeFileWithDirs()` - запись с созданием директорий
**config.test.ts:**
- ✅ Валидная конфигурация
- ❌ Без inputPath
- ❌ Без outputPath
- ✅ Опциональное поле fileName
### 4. Сгенерированный клиент (7 кейсов)
**Компиляция:**
- ✅ TypeScript компиляция без ошибок
- ✅ Отсутствие type errors
- ✅ Корректные импорты/экспорты
**Корректность API:**
-Все endpoints присутствуют
- ✅ Корректные имена методов
- ✅ HttpClient инициализация
- ✅ Метод `setSecurityData`
### 5. Интеграционные E2E (15 кейсов)
**Полный цикл:**
- ✅ CLI → создание → импорт → использование
- ✅ Генерация из локального файла
- ✅ Генерация из URL
- ✅ Повторная генерация
**HTTP с mock:**
- ✅ GET без параметров
- ✅ GET с query параметрами
- ✅ POST с body
- ✅ PUT/PATCH/DELETE
- ✅ Статусы 200, 201, 400, 401, 404, 500
- ❌ Network errors
- ✅ Bearer authentication
- ✅ Custom headers
## Написание новых тестов
### Пример юнит теста
```typescript
import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
import { setupTest } from '../helpers/setup.js';
describe('My Feature', () => {
let tempDir: string;
let cleanup: () => Promise<void>;
beforeEach(async () => {
const setup = await setupTest();
tempDir = setup.tempDir;
cleanup = setup.cleanup;
});
afterEach(async () => {
await cleanup();
});
test('should do something', () => {
// Arrange
const input = 'test';
// Act
const result = myFunction(input);
// Assert
expect(result).toBe('expected');
});
});
```
### Пример интеграционного теста
```typescript
import { describe, test, expect, beforeAll, afterAll } from 'bun:test';
import { createMockServer } from '../helpers/mock-server.js';
describe('Integration Test', () => {
let mockServer;
beforeAll(() => {
mockServer = createMockServer();
mockServer.start();
});
afterAll(() => {
mockServer.stop();
});
test('should make HTTP request', async () => {
const response = await fetch('https://api.example.com/users');
const data = await response.json();
expect(response.status).toBe(200);
expect(Array.isArray(data)).toBe(true);
});
});
```
## Лучшие практики
### 1. Изоляция тестов
- Каждый тест должен быть независимым
- Использовать `beforeEach`/`afterEach` для setup/cleanup
- Не полагаться на порядок выполнения
### 2. Именование
- Описательные названия: `"должен создать файл при корректных параметрах"`
- Группировать с помощью `describe`
- Использовать принцип AAA (Arrange, Act, Assert)
### 3. Очистка ресурсов
- Всегда очищать временные файлы
- Закрывать соединения
- Использовать `afterEach` для гарантии очистки
### 4. Async/Await
- Всегда использовать `async/await` для асинхронных операций
- Не забывать `await` перед промисами
- Устанавливать таймауты для долгих операций
### 5. Mock данные
- Использовать фикстуры для тестовых данных
- Не хардкодить данные в тестах
- Переиспользовать тестовые данные
## Troubleshooting
### Тесты падают с timeout
Увеличьте таймаут для конкретного теста:
```typescript
test('long running test', async () => {
// test code
}, 60000); // 60 секунд
```
### Тесты не очищаются
Проверьте что `cleanup()` вызывается в `afterEach`:
```typescript
afterEach(async () => {
await cleanup();
});
```
### Mock сервер не работает
Убедитесь что:
1. Сервер запущен в `beforeAll`
2. Сервер остановлен в `afterAll`
3. Хендлеры правильно настроены
### Файлы не находятся
Используйте абсолютные пути или пути относительно `__dirname`:
```typescript
const fixturePath = join(__dirname, '../fixtures/test.json');
```
## CI/CD
Тесты автоматически запускаются при:
- Push в любую ветку
- Создании Pull Request
- Перед деплоем
Требования для прохождения CI:
-Все тесты должны пройти
- ✅ Coverage > 80%
- ✅ Нет TypeScript ошибок
- ✅ Нет lint ошибок
## Метрики
### Целевые показатели
- **Coverage:** > 90%
- **Скорость:** < 30 сек для всех тестов
- **Стабильность:** 0 flaky тестов
### Текущие показатели
Запустите `bun test:coverage` для просмотра актуальных метрик.
## Дополнительная информация
- [План тестирования](../TESTING-PLAN.md)
- [Contributing Guidelines](../CONTRIBUTING.md)
- [Bun Test Documentation](https://bun.sh/docs/cli/test)