# План реализации тестирования 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`