Мы устали писать моки и сделали платформу, которая создаёт JUnit-тесты из реального поведения Java-приложения
Привет, меня зовут Дмитрий, я сооснователь BitDive. Мы делаем платформу для тестирования Java-приложений, которая работает принципиально иначе: вместо того чтобы писать моки вручную, мы записываем, как приложение реально работает, и превращаем эту запись в детерминированные JUnit-тесты.
В этой статье расскажу, какую проблему мы решаем, как это работает внутри и почему в 2026 году, когда AI пишет всё больше кода, верификация стала важнее написания.
Проблема: тестирование стоит дороже разработки
Каждый Java-разработчик, работающий с микросервисами на Spring Boot, знает эту боль:
- Мок-ад. Чтобы написать один интеграционный тест, нужно замокать базу данных, два REST-клиента, Kafka-продюсер и Redis. На Mockito-скрипты уходит больше времени, чем на саму бизнес-логику.
- Тесты на фейковых данных. Моки возвращают то, что разработчик придумал, а не то, что реально приходит из базы или API. Тест проходит, а в проде всё падает, потому что реальный ответ выглядит иначе.
- Нестабильные (flaky) тесты. Тесты зависят от порядка выполнения, от состояния тестовой базы, от таймингов. Команда перестаёт доверять сьюту и выкатывает, скрестив пальцы.
- Тест-код растёт быстрее продакшн-кода. Тысячи строк билдеров, фикстур, кастомных матчеров. Рефакторинг бизнес-логики = рефакторинг тестов.
По данным Greptile 2025, объём кода на разработчика вырос на 76% за год. Тестовая инфраструктура не справляется.
Идея: а что, если записать реальное поведение?
Вместо того чтобы придумывать, что должен возвращать мок, мы решили записать, что приложение реально делает, и использовать эту запись как основу для тестов.
BitDive работает как Java Agent: подключается к JVM без изменений в коде приложения и записывает полный контекст выполнения:
- Каждый вызов метода с входными параметрами и возвращаемым значением
- Каждый SQL-запрос с реальными параметрами и результатом
- Каждый HTTP-запрос к downstream-сервисам с заголовками и телом
- Kafka-сообщения, gRPC-вызовы, обращения к Redis
- Исключения с полным стектрейсом и контекстом переменных
Эта запись называется трейс. Один трейс — это полная анатомия одного бизнес-сценария: от входящего HTTP-запроса до последнего SQL-запроса.
Как это работает: три шага
Шаг 1: Захват
Подключаете BitDive Agent к вашему сервису (одна зависимость в pom.xml). Запускаете приложение. Делаете реальные вызовы: через Postman, фронтенд, curl или автотестами. BitDive записывает всё, что происходит внутри JVM.
Overhead: 0.5-5% CPU. Подходит для dev, staging и даже prod в режиме сэмплирования.
Шаг 2: Создание теста
В интерфейсе BitDive выбираете записанный трейс и нажимаете «Создать тест». BitDive формирует JSON Replay Plan, содержащий весь контекст выполнения. Стандартный JUnit 5 runner воспроизводит этот план, автоматически подставляя записанные ответы вместо реальных зависимостей.
Что получаете:
- Стандартный JUnit 5 тест. Запускается через mvn test, IntelliJ, любой CI.
- Все зависимости (БД, API, Kafka, Redis) автоматически замоканы из записанных данных.
- Никакого Mockito-кода. Никаких билдеров и фикстур.
- Тест работает с первого запуска, потому что содержит реальные данные, а не придуманные.
Шаг 3: Верификация
Тесты запускаются в CI/CD как обычные JUnit-тесты. Если кто-то (разработчик или AI-агент) меняет код, тесты детерминированно проверяют, что поведение осталось прежним.
Для межсервисной верификации: делаете тот же API-вызов к обновлённому сервису, BitDive захватывает новый трейс, и вы сравниваете два трейса слой за слоем. Изменилась сериализация? Пропал заголовок? Другой формат ошибки? Видно сразу.
Четыре режима тестирования
Из одного записанного трейса BitDive создаёт тесты на четырёх уровнях:
- Unit-тесты (метод-уровень). Каждый метод тестируется изолированно. Зависимости замоканы. Быстрая обратная связь: без Spring Context, без контейнеров.
- Интеграционные тесты (Replay Mode). Полный Spring Context с реальными бинами и транзакциями. Все внешние зависимости (БД, API, Kafka) воспроизводятся из трейса. Нулевая инфраструктура. Работает где угодно с mvn test.
- Интеграционные тесты (Testcontainers Mode). Реальная база данных через Testcontainers (PostgreSQL, MongoDB, Redis). Внешние API всё ещё воспроизводятся из трейсов. Ловит schema drift, проблемы миграций, реальное SQL-поведение.
- API Verification. Сравнение трейсов до/после изменения кода. Обнаруживает регрессии на границе сервисов: изменение payload, потерю заголовков, изменение формата ошибок.
Кейс: N+1 query
Реальный пример из демо с Cursor AI (YouTube):
- AI-агент (Cursor) запрашивает трейс из BitDive через MCP. Видит: endpoint GET /students выполняет 243 SQL-запроса за один вызов. Классический N+1.
- Агент анализирует код, находит FetchType.EAGER без @EntityGraph.
- Агент добавляет @EntityGraph(attributePaths = {"courses", "courses.teacher"}).
- После деплоя фикса: тот же endpoint — 1 SQL-запрос. Время ответа: 94ms → 13ms.
- Агент сравнивает два трейса слой за слоем: контроллер, сервис, репозиторий. 183 записи студентов — идентичны. Сортировка — сохранена. Фикс ничего не сломал.
AI не гадал. Он видел 243 запроса в трейсе, починил причину понимая бизнес логику и затронутые методы, измерил результат (86% быстрее) и доказал, что ответ остался идентичным.
Почему это важно именно сейчас
В 2026 году AI-ассистенты (Cursor, Claude Code, Copilot) пишут значительную часть кода. Узкое место сместилось: написание кода перестало быть проблемой. Проблема — верификация.
AI видит только статический код. Он не видит, как данные реально сериализуются, какие заголовки добавляются интерцепторами, что конкретно ожидает downstream-сервис. Он может отрефакторить DTO и незаметно сломать JSON-ответ для трёх других сервисов.
BitDive решает это через Model Context Protocol (MCP). AI-агенты в Cursor, Claude Code и Windsurf могут:
- Запрашивать реальные трейсы перед внесением изменений: видеть SQL, параметры, HTTP-обмены
- Верифицировать свои изменения: сравнивать трейсы до/после и доказывать, что ничего не сломали
- Запускать регрессию: mvn test с детерминированными тестами из реальных данных
Мы называем это Autonomous Quality Loop: агент видит реальные данные → вносит изменение → верифицирует по трейсу → запускает регрессию → коммитит с доказательством корректности.
Чем BitDive НЕ является
Важно проговорить, потому что путают:
- BitDive — это не AI-генератор тестов (как Diffblue или Copilot). Мы не угадываем, что тест должен проверять. Мы записываем реальное поведение. Тесты детерминированные и работают с первого запуска.
- BitDive — это не APM (как Datadog или New Relic). Мы не мониторим метрики. Мы захватываем полный контекст выполнения: параметры, возвращаемые значения, SQL result sets — и превращаем их в тесты.
- BitDive — это не service mesh (как Speedscale или Keploy). Мы работаем на уровне JVM, а не на уровне сети. Поэтому видим не только HTTP-трафик, но и внутреннюю логику: какие методы вызвались, с какими параметрами, что вернули.
Технические детали для тех, кому важно
- JVM-инструментация через Java Instrumentation API. Без модификации кода приложения.
- Поддерживаемый стек: Java, Kotlin, Spring Boot. JDBC (PostgreSQL, MySQL, Oracle, MongoDB), HTTP/REST, Kafka, gRPC, Redis.
- Формат тестов: стандартный JUnit 5. Работает с Maven, Gradle, IntelliJ, любым CI.
- Деплой: Docker Compose (self-hosted) или SaaS. Поднимается за минуты.
- Безопасность: PII-маскирование (emails, карты, токены) до того, как данные покинут память приложения. Zero Trust Architecture.
- Overhead: 0.5-5% CPU. Кастомный бинарный формат для сериализации событий.
Как попробовать
- Зарегистрируйтесь на bitdive.io (бесплатный Starter-план)
- Добавьте зависимость BitDive в pom.xml
- Запустите приложение и сделайте пару API-вызовов
- В интерфейсе BitDive выберите трейс → «Создать тест»
- Запустите mvn test
От регистрации до первого работающего теста — около 15 минут.
Если есть вопросы — пишите в комментариях, отвечу.