# Документация по тестированию 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; 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)