# Тестирование llm-proxy Все тесты — обычные модульные, живут в `src/commonTest/kotlin/pw/binom/llmproxy/`. ## Запуск - `./gradlew jvmTest` — прогнать все тесты; - `./gradlew clean jvmTest fatJar` — полная сборка с нуля; - результат смотреть в `build/test-results/jvmTest/*.xml` (атрибуты `tests`/`failures`/`errors`), потому что строки вида «N tests completed» печатаются только при падениях. ## Что покрыто | Файл | Что проверяет | | --- | --- | | `ThinkTagSplitterTest` | Автомат рассечения think-тегов: passthrough при off, вырезание рассуждений при split, отбрасывание при strip, удержание разрезанного тега, несколько блоков, незакрытый блок; | | `ConfigLogicTest` | Разбор конфига, приоритет источников (апстрим важнее провайдера), слияние патчей, выбор апстрима и лимиты конкурентности, заголовки, сессии; | | `ThinkTagTransformTest` | Non-stream путь `transformThinkMessage`: перенос рассуждений в `reasoning_content`, дописывание к уже имеющемуся, strip, незакрытый блок, отсутствие изменений → null; | | `ThinkTagChunkTest` | SSE-чанки `transformThinkChunk`: удержание хвоста тега между чанками, независимые сплиттеры по index, удаление пустого `content`; | | `ThinkTagStreamTest` | Обвязка стрима `streamSseWithThinkTags`: разрез тега между data-событиями, сброс удержанного хвоста в финиш-чанке, прохождение служебных строк и `[DONE]`, битый JSON, чанк без choices, strip. | ## Проверка качества тестов (мутационная приёмка) Приём по шагам: 1. Забэкапить файл. 2. Внести РОВНО одну поломку в боевой код. 3. Прогнать `./gradlew cleanJvmTest jvmTest`. 4. Посмотреть XML — тест, который не упал, считается пустым. 5. Откатить (`git checkout -- <файл>`). Обязательно: `cleanJvmTest` обязателен, иначе прогон не перезапустится. Проверенные мутации, каждая из которых ДОЛЖНА ронять тесты: - `transformThinkMessage` возвращает null → падают тесты non-stream; - `transformThinkChunk` возвращает null → падают тесты чанков и стрима; - блок финиш-чанка в `streamSseWithThinkTags` не выполняется → падает тест про удержанный хвост; - `holdableSuffix` всегда 0 (хвост тега не удерживается) → падают тесты автомата, чанков и стрима; - `strip` начинает отдавать рассуждения → падает тест автомата. Правило: боевой код нельзя подгонять под тест; если тест не проходит, неверен тест. ## Известное ограничение Живой стрим в реальном апстриме модульными тестами не проверяется: обвязка испытывается на синтетическом SSE через каналы ktor. Реальный апстрим проверяется только после деплоя.