e2e интеграционные тесты

This commit is contained in:
2025-10-28 11:09:37 +03:00
parent 4e2d0f03de
commit 3c3ac80713
2 changed files with 0 additions and 535 deletions

View File

@@ -1,393 +0,0 @@
# План реализации тестирования API CodeGen
## Общая информация
**Цель:** Максимальное покрытие тестами CLI инструмента и сгенерированного клиента
**Итого тестовых кейсов:** ~72
**Запуск:** `bun test` (одна команда)
---
## Технологический стек
### Основные инструменты
- [x] **Bun test** - встроенный test runner (быстрый, совместим с Jest API)
- [ ] **msw** `^2.0.0` - Mock Service Worker для HTTP мокирования
- [ ] **tmp** `^0.2.1` - создание временных директорий для тестов
- [ ] **@types/tmp** `^0.2.6` - типы для tmp
- [ ] **execa** `^8.0.0` - запуск CLI команд в тестах
### Преимущества выбранного стека
- ✅ Быстрое выполнение тестов (Bun)
- ✅ Реалистичное HTTP мокирование (msw)
- ✅ Изолированное тестовое окружение (tmp)
- ✅ Удобное тестирование CLI (execa)
- ✅ Совместимость с Jest API (легкая миграция при необходимости)
---
## Структура проекта с тестами
```
api-codegen/
├── tests/
│ ├── fixtures/ # Тестовые OpenAPI спецификации
│ │ ├── minimal.json # Минимальная валидная спецификация
│ │ ├── valid.json # Полная валидная спецификация
│ │ ├── complex.json # Сложная (100+ endpoints)
│ │ ├── invalid.json # Невалидная спецификация
│ │ ├── with-auth.json # С authentication схемами
│ │ ├── edge-cases.json # Unicode, спецсимволы
│ │ └── empty.json # Пустая спецификация
│ │
│ ├── unit/ # Юнит тесты
│ │ ├── cli.test.ts # Тесты CLI команд
│ │ ├── generator.test.ts # Тесты генератора
│ │ ├── config.test.ts # Тесты валидации конфигурации
│ │ └── utils/
│ │ └── file.test.ts # Тесты файловых утилит
│ │
│ ├── integration/ # Интеграционные тесты
│ │ ├── e2e-generation.test.ts # End-to-end генерация
│ │ └── generated-client.test.ts # Тесты сгенерированного клиента
│ │
│ └── helpers/ # Вспомогательные функции
│ ├── setup.ts # Настройка окружения
│ ├── mock-server.ts # Mock HTTP сервер (msw)
│ └── fixtures.ts # Утилиты для работы с фикстурами
└── package.json
```
---
## Этапы реализации
### Этап 1: Подготовка инфраструктуры
#### 1.1. Установка зависимостей
- [ ] Добавить `msw` в devDependencies
- [ ] Добавить `tmp` и `@types/tmp` в devDependencies
- [ ] Добавить `execa` в devDependencies
- [ ] Выполнить `bun install`
#### 1.2. Создание структуры директорий
- [ ] Создать `tests/`
- [ ] Создать `tests/fixtures/`
- [ ] Создать `tests/unit/`
- [ ] Создать `tests/unit/utils/`
- [ ] Создать `tests/integration/`
- [ ] Создать `tests/helpers/`
#### 1.3. Настройка package.json
- [ ] Добавить скрипт `"test": "bun test"`
- [ ] Добавить скрипт `"test:unit": "bun test tests/unit"`
- [ ] Добавить скрипт `"test:integration": "bun test tests/integration"`
- [ ] Добавить скрипт `"test:watch": "bun test --watch"`
- [ ] Добавить скрипт `"test:coverage": "bun test --coverage"`
---
### Этап 2: Создание тестовых фикстур
#### 2.1. minimal.json - минимальная спецификация
- [ ] Базовая структура OpenAPI 3.0
- [ ] Один GET endpoint
- [ ] Минимальная info секция
- [ ] Без servers
- [ ] Простой response
#### 2.2. valid.json - полная валидная спецификация
- [ ] Все основные HTTP методы (GET, POST, PUT, PATCH, DELETE)
- [ ] Path параметры
- [ ] Query параметры
- [ ] Request body (JSON)
- [ ] Response schemas
- [ ] Базовые типы данных
- [ ] Описания и примеры
- [ ] Servers с baseUrl
#### 2.3. complex.json - сложная спецификация
- [ ] 100+ endpoints
- [ ] Вложенные объекты
- [ ] Массивы объектов
- [ ] Enum типы
- [ ] Референсы ($ref)
- [ ] Множественные tags
- [ ] Различные content types
#### 2.4. with-auth.json - с аутентификацией
- [ ] Bearer token authentication
- [ ] API Key authentication
- [ ] Security schemes
- [ ] Защищенные endpoints
#### 2.5. edge-cases.json - edge cases
- [ ] Unicode символы в названиях
- [ ] Специальные символы в путях
- [ ] Очень длинные названия
- [ ] Зарезервированные слова
- [ ] Нестандартные HTTP методы
#### 2.6. invalid.json - невалидная спецификация
- [ ] Отсутствующие обязательные поля
- [ ] Неправильная структура
- [ ] Невалидные типы данных
#### 2.7. empty.json - пустая спецификация
- [ ] Только обязательные поля
- [ ] Без paths
- [ ] Без components
---
### Этап 3: Вспомогательные функции
#### 3.1. tests/helpers/setup.ts
- [ ] `beforeEach` для инициализации
- [ ] `afterEach` для очистки
- [ ] Создание временных директорий
- [ ] Очистка временных файлов
#### 3.2. tests/helpers/mock-server.ts
- [ ] Настройка MSW
- [ ] Mock handlers для разных endpoints
- [ ] Симуляция различных HTTP статусов
- [ ] Симуляция network errors
- [ ] Симуляция timeouts
#### 3.3. tests/helpers/fixtures.ts
- [ ] Загрузка фикстур
- [ ] Валидация OpenAPI спецификаций
- [ ] Создание тестовых конфигураций
- [ ] Утилиты для сравнения сгенерированного кода
---
### Этап 4: Юнит тесты CLI (15 кейсов)
#### 4.1. tests/unit/cli.test.ts - базовые сценарии
- [ ] ✅ Запуск с корректными параметрами (локальный файл)
- [ ] ✅ Запуск с URL в качестве input
- [ ] ✅ Генерация с кастомным именем файла
- [ ] ✅ Генерация с автоматическим именем (из OpenAPI title)
- [ ] ✅ Отображение версии `--version`
- [ ] ✅ Отображение help `--help`
#### 4.2. tests/unit/cli.test.ts - обработка ошибок
- [ ] ❌ Отсутствие обязательного параметра `--input`
- [ ] ❌ Отсутствие обязательного параметра `--output`
- [ ] ❌ Несуществующий входной файл
- [ ] ❌ Некорректный формат OpenAPI
- [ ] ❌ Недоступный URL (404)
- [ ] ❌ Недоступный URL (network error)
- [ ] ❌ Невозможность записи в output директорию (permissions)
- [ ] ❌ Невалидный JSON в input файле
- [ ] ❌ YAML файл (должен работать или показать понятную ошибку)
---
### Этап 5: Юнит тесты генератора (20 кейсов)
#### 5.1. tests/unit/generator.test.ts - корректная генерация
- [ ] ✅ Создание выходного файла
- [ ] ✅ Корректная структура сгенерированного кода
- [ ] ✅ Обработка GET запросов
- [ ] ✅ Обработка POST запросов
- [ ] ✅ Обработка PUT запросов
- [ ] ✅ Обработка PATCH запросов
- [ ] ✅ Обработка DELETE запросов
- [ ] ✅ Генерация типов для request parameters
- [ ] ✅ Генерация типов для response
- [ ] ✅ Обработка path параметров
- [ ] ✅ Обработка query параметров
- [ ] ✅ Обработка request body
- [ ] ✅ Генерация enum'ов
- [ ] ✅ Обработка Bearer authentication
- [ ] ✅ Применение хука `onFormatRouteName` (убирание "Controller")
- [ ] ✅ Использование baseUrl из OpenAPI servers
#### 5.2. tests/unit/generator.test.ts - edge cases
- [ ] ❌ Пустая OpenAPI спецификация
- [ ] ❌ Минимальная спецификация (только paths)
- [ ] ❌ Очень большая спецификация (100+ endpoints)
- [ ] ❌ Unicode символы в именах методов/типов
---
### Этап 6: Юнит тесты утилит (10 кейсов)
#### 6.1. tests/unit/utils/file.test.ts
- [ ]`fileExists()` - существующий файл возвращает true
- [ ]`fileExists()` - несуществующий файл возвращает false
- [ ]`readJsonFile()` - чтение локального файла
- [ ]`readJsonFile()` - чтение файла по URL
- [ ]`readJsonFile()` - невалидный JSON выбрасывает ошибку
- [ ]`readJsonFile()` - недоступный URL выбрасывает ошибку
- [ ]`ensureDir()` - создание директории
- [ ]`ensureDir()` - создание вложенных директорий
- [ ]`writeFileWithDirs()` - запись файла с автосозданием директорий
#### 6.2. tests/unit/config.test.ts
- [ ] ✅ Валидация корректной конфигурации успешна
- [ ] ❌ Валидация без inputPath выбрасывает ошибку
- [ ] ❌ Валидация без outputPath выбрасывает ошибку
- [ ] ✅ Опциональное поле fileName работает
---
### Этап 7: Тесты сгенерированного клиента (7 кейсов)
#### 7.1. tests/integration/generated-client.test.ts - компиляция
- [ ] ✅ TypeScript компиляция без ошибок
- [ ] ✅ Отсутствие type errors
- [ ] ✅ Корректные импорты и экспорты
#### 7.2. tests/integration/generated-client.test.ts - корректность API
- [ ]Все endpoints из спецификации присутствуют
- [ ] ✅ Корректные имена методов (без "Controller" префиксов)
- [ ] ✅ HttpClient правильно инициализируется
- [ ] ✅ Метод `setSecurityData` работает
---
### Этап 8: Интеграционные E2E тесты (15 кейсов)
#### 8.1. tests/integration/e2e-generation.test.ts - полный цикл
- [ ] ✅ CLI генерация → создание файла → импорт → использование
- [ ] ✅ Генерация из локального файла
- [ ] ✅ Генерация из URL
- [ ] ✅ Повторная генерация (перезапись файлов)
#### 8.2. tests/integration/e2e-generation.test.ts - HTTP запросы с mock
- [ ] ✅ GET запрос без параметров
- [ ] ✅ GET запрос с query параметрами
- [ ] ✅ POST запрос с body
- [ ] ✅ PUT запрос
- [ ] ✅ PATCH запрос
- [ ] ✅ DELETE запрос
- [ ] ✅ Обработка 200 статуса
- [ ] ✅ Обработка 201 статуса
- [ ] ❌ Обработка 400 статуса (Bad Request)
- [ ] ❌ Обработка 401 статуса (Unauthorized)
- [ ] ❌ Обработка 404 статуса (Not Found)
- [ ] ❌ Обработка 500 статуса (Server Error)
- [ ] ❌ Обработка network errors
- [ ] ✅ Bearer token authentication
- [ ] ✅ Custom headers
---
### Этап 9: Тесты производительности (5 кейсов)
#### 9.1. tests/integration/performance.test.ts
- [ ] ✅ Генерация маленькой спецификации (< 1 секунды)
- [ ] Генерация средней спецификации (< 3 секунд)
- [ ] Генерация большой спецификации (< 10 секунд)
- [ ] Параллельная генерация нескольких проектов
- [ ] Повторная генерация не замедляется
---
### Этап 10: Настройка CI (опционально)
#### 10.1. GitHub Actions
- [ ] Создать `.github/workflows/test.yml`
- [ ] Настроить запуск тестов на push
- [ ] Настроить запуск тестов на PR
- [ ] Добавить badge в README.md
#### 10.2. Pre-commit hooks
- [ ] Установить husky
- [ ] Добавить pre-commit хук для запуска тестов
- [ ] Добавить lint-staged для проверки только измененных файлов
---
### Этап 11: Документация
#### 11.1. Обновление README.md
- [ ] Добавить секцию "Тестирование"
- [ ] Описать команды запуска тестов
- [ ] Добавить информацию о coverage
- [ ] Добавить примеры запуска конкретных тестов
#### 11.2. Создание CONTRIBUTING.md
- [ ] Правила написания тестов
- [ ] Структура тестов
- [ ] Как добавить новый тест
- [ ] Требования к coverage
---
## Команды для разработки
```bash
# Установка зависимостей
bun install
# Запуск всех тестов
bun test
# Запуск только юнит тестов
bun test:unit
# Запуск только интеграционных тестов
bun test:integration
# Запуск в watch режиме
bun test:watch
# Запуск с coverage
bun test:coverage
# Запуск конкретного файла
bun test tests/unit/cli.test.ts
# Запуск конкретного теста
bun test -t "should generate client with custom name"
```
---
## Метрики успеха
### Критерии завершения
- Все 72 тестовых кейса реализованы
- Coverage > 80% (желательно > 90%)
-Все тесты проходят успешно
- ✅ Время выполнения всех тестов < 30 секунд
- CI настроен и работает
- Документация обновлена
### Показатели качества
- 🎯 **Coverage:** > 90%
- 🎯 **Скорость:** < 30 сек для всех тестов
- 🎯 **Стабильность:** 0 flaky тестов
- 🎯 **Читаемость:** Понятные названия и описания
- 🎯 **Поддерживаемость:** Минимум дублирования кода
---
## Следующие шаги
После завершения всех этапов:
1. **Переключение в режим Code** для реализации
2. **Пошаговая реализация** согласно чек-листам
3. **Проверка coverage** после каждого этапа
4. **Рефакторинг** при необходимости
5. **Финальная проверка** всех тестов
---
## Примечания
- Все тесты должны быть изолированными и не зависеть друг от друга
- Использовать temporary directories для всех файловых операций
- Очищать ресурсы после каждого теста (cleanup)
- Следовать принципу AAA (Arrange, Act, Assert)
- Использовать описательные имена тестов
- Группировать связанные тесты с помощью `describe`

View File

@@ -172,148 +172,6 @@ bun test -t "should generate client with custom name"
- ✅ 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` для просмотра актуальных метрик.
## Дополнительная информация