Skip to main content
Glama

TestTrout

Тестовый ассистент для приложений, созданных ИИ.

Запускайте его как приложение или передайте своему кодинг-агенту через MCP. В любом случае он пишет тесты, которых у вашего приложения никогда не было, и сообщает, когда они ломаются.

License Python Status


Форель — индикаторный вид. Она живёт только в чистой, хорошо аэрированной воде — если нашли её в ручье, значит, вода здорова, и проверять её не нужно.

Именно так выглядит хороший набор тестов: не рутина, а сигнал, который можно прочитать с одного взгляда.


Проблема

Кодинг-агенты работают быстро. Они также тихо ломают вещи, и в приложениях, которые они создают — Lovable, v0, Bolt, самописный React на Vercel — почти никогда нет тестов. Поэтому цикл заканчивается фразой «выглядит нормально» от того, кто только что написал код.

TestTrout замыкает этот цикл. Он читает репозиторий, подключается к работающему деплою, выясняет, что не покрыто тестами и в каком порядке это важно, пишет настоящие тесты, запускает их и сообщает результаты, на которые действительно можно реагировать.

Related MCP server: Lastest

Запуск

pip install testtrout
trout up

Хранилище, воркер и интерфейс на localhost:7411. Без Docker, без демона, без установки базы данных — SQLite в ~/.testtrout, воркер в процессе. Никаких API-ключей какого-либо рода. Здесь ничего не вызывает модель.

Как это работает

Добавьте проект — папку на этой машине и URL, по которому он развёрнут.

trout add ~/code/my-app --url https://my-app.vercel.app

Затем четыре шага, которые также являются четырьмя командами:

trout look     # read the code, ask the deployment, work out what is testable
trout facts    # what I still need from you — all optional
trout build    # write the baseline and prove it
trout run      # re-run it and report what changed

Базовый уровень — это то, что ваш деплой делает сегодня. TestTrout записывает это и проверяет, что оно продолжает происходить. Он не знает, является ли текущее поведение правильным — никто ему этого не сказал — и никогда не спросит. Он знает, каково поведение, и замечает день, когда оно меняется.

Именно это правило объясняет, почему нет интервью, очереди на одобрение и списка вопросов о вашем продукте. Единственное, о чём он просит, — это конкретные значения, которые он не может обнаружить сам:

Он спрашивает

Потому что

URL деплоя

Ничего нельзя тестировать только по коду

URL API

Только если ваш бэкенд развёрнут на отдельном хосте

Аккаунт

Только когда что-то действительно отказало в неаутентифицированном запросе

Настоящий id

Только когда пробник не смог сам добраться до /jobs/:id

На каждый вопрос можно ответить за секунды, каждый необязателен, и каждый поясняет, что он открывает. Дайте только URL — и получите все страницы, которые загружаются без входа, а для большинства приложений это уже полезный набор.

Всё, что он выясняет, сохраняется как артефакт на боковой панели — карта проекта, форма, план тестов, базовый набор — так что ничего важного не теряется на три экрана выше в прокрутке чата.

Или оставайтесь в своём кодинг-агенте

Приложение — один из способов входа, но не единственный. Всё, что оно делает, доступно как типизированные MCP инструменты и как CLI-команды, так что тем, кто предпочитает не покидать редактор, не придётся:

pip install 'testtrout[mcp]'
trout mcp /path/to/your/project

Укажите агенту на навык в .claude/skills/ или скажите:

Используй MCP-сервер TestTrout. Посмотри на репозиторий, скажи, что ему ещё нужно от меня, затем построй базовый уровень и запусти его.

Семь инструментов, привязанных к одному проекту, чтобы агент не мог действовать с неправильным репозиторием:

look

Читает код, спрашивает деплой, выясняет, что тестируемо.

facts set_facts

Какие конкретные значения отсутствуют; сохраняет то, что даёт пользователь.

plan

Что можно тестировать сейчас и что нужно каждому заблокированному пункту.

build

Пишет базовый уровень и проверяет его против деплоя.

run suite

Перезапускает его и читает, что делает каждый тест.

Плюс trout://map, trout://facts, trout://plan, trout://config, trout://scenarios как ресурсы, чтобы объёмное состояние не вытесняло контекстное окно агента.

Что он понимает

trout look читает код вообще без доступа к сети, так что он безопасен для репозитория, который вы только что склонировали. В типичном приложении на Supabase он находит:

Поверхность

Пример

Экраны

/orders/:idOrderDetail и данные, к которым он обращается

Операции с данными

supabase.from('orders').delete().eq('id', …)

RLS-политики

Users manage own orders — тестируемое утверждение об авторизации

Серверные действия

Функции 'use server' — конечные точки, похожие на хелперы

Обработчики маршрутов

app/api/checkout/route.tsPOST

Сторонние сервисы

Stripe, Resend — граница подстановки

Схема

Таблицы, колонки, внешние ключи, статус RLS

Он также сообщает, когда таблица записывается из браузерного кода без защиты на уровне строк — то есть она доступна на запись всему миру через анонимный ключ. Обычно это новость.

Он никогда не просит вашу базу данных

Тесты обращаются к вашему приложению так же, как пользователь: HTTP к вашим конечным точкам и настоящий браузер к вашему интерфейсу. Вход выполняется через вашу собственную форму логина, которую trout look находит один раз, чтобы тесты воспроизводили известную форму, а не угадывали.

Итак, всему этому нужны URL и два тестовых аккаунта. Никакого анонимного ключа, никакой сервисной роли, никаких учётных данных проекта — ничего, что большинство команд обоснованно отказались бы передавать инструменту для тестирования.

Авторизация при этом покрыта, и, возможно, даже лучше: войдя как два обычных аккаунта, то, что видит один, не должен видеть другой. Это проверяет ваши политики и всё, что ваше приложение добавляет поверх них, — а именно с этим сталкивается реальный пользователь.

Почему тестам можно доверять

Он строит базовый уровень, а не догадки для каждого PR. Тест, выведенный из кода, который вы только что изменили, утверждает, что новое поведение корректно по построению — он не может поймать регрессию. TestTrout сначала сертифицирует набор против работающего деплоя, поэтому сбой означает что-то реальное.

Никакой модели, нигде. Ни при сканировании, ни при планировании, ни при написании теста. Каждое утверждение прослеживается до того, что деплой действительно сделал, поэтому одинаковые входные данные всегда дают одинаковый набор и не нужно настраивать API-ключ.

Каждое утверждение несёт своё происхождение, и в базовом уровне оно всегда observed — с доказательствами, записанными в сгенерированный файл:

// observed: the page title when /orders was loaded
await expect(page).toHaveTitle('Orders');
// observed: seen on /orders at baseline
await expect(page.getByTestId('orders-table')).toBeVisible();

Он отправляет только GET. Тесты конечных точек воспроизводят запрос, который сделал пробник, независимо от методов, объявленных конечной точкой, так что направление этого на продакшн не может ничего там изменить.

Сбой классифицируется до того, как о нём сообщается. Только assertion_failure — это сигнал о продукте. Ошибки аутентификации, недоступные базы данных и заблокированные сторонние вызовы относятся к обвязке, и неубедительный прогон никогда не повышается до прохода.

Всё из терминала

trout add ~/code/my-app --url https://my-app.vercel.app
trout look          # read the code, ask the deployment
trout facts         # what I still need — all optional
trout build         # write the baseline and prove it
trout run           # re-run it; a failure means behaviour changed

Каждая команда поддерживает --json. Полное руководство в docs/setup.md.

Как он хранит данные

Ваш набор тестов остаётся в вашем репозитории, в коммитах и доступен для ревью:

.trout/scenarios/*.yaml    what each test asserts, in plain language
.trout/facts.yaml          what was asked for — never a secret value
.trout/plan.yaml           what can be tested, and what is waiting
.trout/config.yaml         deployments and env: references, never secrets
tests/trout/               generated Playwright and Vitest files

История прогонов, покрытие со временем и очередь заданий хранятся в SQLite в ~/.testtrout. Это разделение намеренно: набор должен находиться рядом с кодом, где его может проверить pull request, а вопросы, на которые файлы не могут ответить — становится ли тест более флаки, растёт ли покрытие — должны быть в базе данных.

Необязательный веб-интерфейс

trout web

Покрытие с первого взгляда, ранжированный список пробелов, просмотр сценариев, история прогонов с доказательствами, живой лог. Те же файлы .trout/, что и в CLI — без базы данных, ничего не хостится, только loopback. Полностью необязателен; CLI и MCP самодостаточны.

Безопасность

Инструменту нужны учётные данные вашей базы данных, и он может управлять вашим деплоем, поэтому гарантии обеспечиваются в коде, а не просто документируются:

  • Продакшн по умолчанию доступен только для чтения. Мутирующие запросы блокируются на сетевом уровне, если конечная точка явно не помечена как disposable. Защита находится ниже навигации, потому что утверждение «просто загрузка страницы — это чтение» ложно — многие такие приложения пишут при монтировании. Ни агент, ни веб-клик не могут изменить эту настройку.

  • Сторонние сервисы перехватываются. Тестовый прогон не может списать деньги с карты или отправить письмо клиенту. Несопоставленные исходящие запросы громко падают; мок, который молча ничего не сопоставляет, — это способ получить зелёный набор, который ничего не тестирует.

  • Секреты не попадают в коммитируемые файлы. .trout/config.yaml содержит только ссылки env:. Значения хранятся в .env, который в .gitignore.

  • Ничего не хостится, и ничего не покидает вашу машину. Нет модели, которую нужно вызывать, и нет аккаунта, который нужно создавать. Никакой телеметрии.

Поддерживаемые стеки

React + Vite (Lovable, v0, Bolt) и Next.js App Router, на TypeScript, с Supabase, развёрнутые где угодно, доступные по HTTP. Аутентификация через Supabase, Clerk или NextAuth.

Намеренно узко. Глубина на одном стеке лучше, чем поверхностное покрытие многих — и эти кодовые базы достаточно регулярны, чтобы статический анализ был по-настоящему точным. Другие стеки — это один адаптер: см. docs/adapters.md.

Дорожная карта

Анализ репозитория, исследование деплоя, ранжирование пробелов

Создание сценариев, генерация, выполнение, сертификация

MCP-сервер, CLI и локальное приложение с хранилищем и воркером

Выбор тестов на основе изменений, дифференциал базовой ветки

Мультирепозиторность: связывание локальных папок или клонирование с GitHub-токеном

Полная конфигурация из интерфейса или CLI, с обнаружением учётных данных

🔜

Проверки в pull request на GitHub

🔜

Индекс наблюдаемого покрытия (сегодняшний выбор использует заявленное покрытие)

Участие

Добавление фреймворка, провайдера аутентификации или тест-раннера означает реализацию одного протокола и регистрацию точки входа — форк не требуется. См. CONTRIBUTING.md и docs/adapters.md.

Полный набор тестов запускается офлайн без API-ключа. Это намеренно, и это стоит сохранить.

Лицензия

Apache 2.0

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/DrDroidLab/TestTrout'

If you have feedback or need assistance with the MCP directory API, please join our Discord server