TL;DR
Если вас заставляют делать N запросов к локальному DeepSeek в день — эта статья про то, как получать от них реальную пользу. Покажу, как с помощью Roo Code разобраться в чужом модульном Android-проекте и написать Kaspresso-тесты за 20 минут вместо нескольких часов. С конкретными промптами и решением проблемы «невидимых» id элементов.
Проблема, о которой не говорят вслух
Многие компании сейчас внедряют AI — кто добровольно, кто принудительно. Разворачивают локальный DeepSeek, устанавливают нормы: столько-то запросов в день, столько-то в месяц. Метрики есть, а польза? ?
Знакомая ситуация?
Чат с DeepSeek открыт в соседней вкладке
Вы копируете туда куски кода и получаете абстрактные ответы
AI не видит ваш проект, не понимает контекст
В итоге запросы делаются «для галочки»
Проблема не в AI и не в инженере. Проблема в инструменте.
Чат без интеграции с кодом — это Google с человеческим лицом. Он не знает, что у вас 12 модулей, не видит ваши layouts, не понимает, какие тесты уже написаны.
Roo Code подключается к тому же DeepSeek, но работает внутри IDE. Те же запросы — но с контекстом всего проекта. Разница как между «гуглить симптомы» и «показать снимок врачу».
Типичные боли QA-инженера
1. Модульный проект — чёрный ящик
app/
├── feature-auth/
├── feature-booking/
├── feature-profile/
├── core-ui/
├── core-network/
└── core-analytics/
Откуда берётся этот BookingViewModel? Где живёт RoomRepository? В каком модуле искать экран, который вы тестируете?
Новый человек в команде тратит первую неделю на археологию вместо тестов.
2. Элементы без id или с динамическими id
// Тест падает с ошибкой:
// NoMatchingViewException: No views in hierarchy found matching...
onView(withId(R.id.booking_button)).perform(click())
Элемент есть на экране, но тест его «не видит». Причины: Compose без testTag, RecyclerView с динамикой, кастомные View, элемент скрыт по умолчанию.
3. Миграция между фреймворками
Команда долго писала на Espresso, потом безопасники попросили сменить инструмент. Переписывать 200 тестов вручную?
Решение: Roo Code + ваш корпоративный DeepSeek
Roo Code — расширение для VS Code (и форков: Cursor, Windsurf), которое работает с полным контекстом проекта.
Ключевое отличие от чата:
Чат с DeepSeek |
Roo Code + DeepSeek |
|---|---|
Видит только то, что вы скопировали |
Видит всю структуру проекта |
Не знает про другие модули |
Анализирует зависимости между модулями |
Ответы абстрактные |
Ответы с конкретными путями к файлам |
Код нужно копировать вручную |
Создаёт файлы напрямую в проекте |
Не знает про ваши существующие тесты |
Видит стиль команды и следует ему |
Важно: Roo Code — это не другая модель. Это способ использовать тот же DeepSeek, который у вас уже развёрнут, но эффективно.
Подключение к вашему корпоративному DeepSeek
Вариант 1: DeepSeek через Ollama
1. Установите расширение Roo Code в VS Code
2. Откройте Roo Code → Settings (шестерёнка)
3. API Provider: выберите "Ollama"
4. Base URL: http://localhost:11434
(или IP сервера: http://192.168.1.100:11434)
5. Model: deepseek-r1:7b (или какая версия у вас установлена)
Вариант 2: Корпоративный API-сервер (OpenAI-совместимый)
Большинство корпоративных решений разворачивают модели с OpenAI-совместимым API:
1. API Provider: "OpenAI Compatible"
2. Base URL: адрес сервера (спросите у DevOps, например http://llm.company.local:8000/v1)
3. API Key: ключ от админов (или пустой, если авторизация отключена)
4. Model ID: название модели на сервере (уточните у DevOps)
Проверка подключения
После настройки отправьте тестовый запрос:
Привет! Какую модель ты используешь?
Если всё работает — получите ответ с названием модели.
Типичные проблемы:
Ошибка |
Причина |
Решение |
|---|---|---|
Connection refused |
Сервер недоступен |
Проверьте URL и сетевой доступ |
401 Unauthorized |
Неверный API Key |
Уточните ключ у администратора |
Model not found |
Неверное имя модели |
Проверьте точное название на сервере |
Практика: от экрана до теста за 20 минут
Исходные данные
Android-проект с модульной структурой
Вы не знаете проект досконально
Задача: написать UI-тесты для экрана бронирования
Фреймворк: Kaspresso
Шаг 1: Разведка проекта (3 минуты)
Откройте проект в VS Code с Roo Code.
Режим: Ask (для анализа)
Проанализируй структуру проекта и ответь:
1. Какие модули отвечают за функциональность бронирования?
2. Где находятся экраны (Activity/Fragment) для бронирования?
3. Какие ViewModel и Repository используются?
4. Есть ли уже написанные UI-тесты? Если да — какой фреймворк?
Формат: краткий список с путями к файлам
Что вы получите:
## Модули бронирования
- `feature-booking` — основная логика
- `core-ui` — переиспользуемые компоненты (RoomCard, TimeSlotPicker)
- `core-network` — API клиент
## Экраны
- `BookingListFragment` → feature-booking/src/main/java/.../ui/list/
- `BookingDetailFragment` → feature-booking/src/main/java/.../ui/detail/
- `CreateBookingFragment` → feature-booking/src/main/java/.../ui/create/
## Существующие тесты
- Найдено 23 UI-теста в `app/src/androidTest/`
- Фреймворк: Kaspresso 1.5.3
- Паттерн: Screen Object в `screens/` директории
3 минуты — и вы понимаете архитектуру лучше, чем после часа чтения кода.
Это тот же DeepSeek, те же запросы в вашу норму — но с реальным результатом.
Шаг 2: Изучение стиля команды (2 минуты)
Покажи пример существующего Kaspresso-теста из проекта.
Какие Screen Objects уже созданы?
Какой naming convention используется?
Теперь вы знаете, как писать тесты консистентно с командой.
Шаг 3: Создание Screen Object (5 минут)
Режим: Code (для генерации)
Создай Kaspresso Screen Object для CreateBookingFragment.
Требования:
1. Проанализируй layout файла fragment_create_booking.xml
2. Найди все интерактивные элементы
3. Используй стиль существующих Screen Objects из проекта
4. Если у элемента нет android:id — предложи альтернативный способ поиска
5. Добавь KDoc комментарии
Сохрани в: app/src/androidTest/java/.../screens/CreateBookingScreen.kt
Результат — готовый Screen Object с обработкой элементов без id:
object CreateBookingScreen : KScreen<CreateBookingScreen>() {
override val layoutId: Int = R.layout.fragment_create_booking
override val viewClass: Class<*> = CreateBookingFragment::class.java
/** Поле выбора даты */
val datePickerField = KEditText { withId(R.id.date_picker_field) }
/** Список доступных комнат */
val roomsList = KRecyclerView(
builder = { withId(R.id.rooms_recycler) },
itemTypeBuilder = { itemType(::RoomItem) }
)
/** Кнопка подтверждения */
val confirmButton = KButton { withId(R.id.confirm_booking_button) }
// ⚠️ Элемент без id — альтернативный поиск
/** Сообщение об ошибке (нет id, ищем по тексту) */
val errorMessage = KView {
withText(R.string.booking_error_message)
}
/** Лоадер (нет id, ищем по content description) */
val loadingIndicator = KView {
withContentDescription("Loading")
}
}
Шаг 4: Решение проблемы «невидимых» элементов (5 минут)
Вот та самая боль: тест не видит элемент.
В CreateBookingFragment есть кнопка "Забронировать", но тест падает с NoMatchingViewException.
Проанализируй:
1. Layout файл fragment_create_booking.xml
2. Код фрагмента CreateBookingFragment.kt
3. Возможные причины проблемы
Предложи решения для Kaspresso.
AI проанализирует ваш конкретный код и найдёт причину:
## Причина найдена
Кнопка "Забронировать" имеет `visibility="gone"` по умолчанию.
Она появляется только после выбора комнаты и времени.
## Решение для Kaspresso
// Дождаться появления кнопки:
step("Ждём появления кнопки") {
CreateBookingScreen {
confirmButton {
// Kaspresso автоматически ждёт до 10 сек
isVisible()
click()
}
}
}
Это не абстрактный совет из интернета — это анализ вашего конкретного кода.
Шаг 5: Генерация тест-кейсов (5 минут)
На основе анализа CreateBookingFragment создай набор тест-кейсов для Kaspresso.
Требования:
1. Покрой happy path и основные edge cases
2. Используй step() для читаемости
3. Следуй стилю существующих тестов проекта
Сохрани в: app/src/androidTest/java/.../tests/CreateBookingTest.kt
Бонус: миграция с Espresso на Kaspresso
Если нужно переписать ст��рые тесты:
В папке app/src/androidTest/java/.../espresso/ находятся старые Espresso-тесты.
Мигрируй LoginEspressoTest.kt на Kaspresso:
1. Сохрани логику тестов
2. Преобразуй в Screen Object паттерн
3. Добавь step() для читаемости
Было (Espresso):
@Test
fun testSuccessfulLogin() {
onView(withId(R.id.email_input))
.perform(typeText("test@example.com"))
onView(withId(R.id.password_input))
.perform(typeText("password123"))
onView(withId(R.id.login_button))
.perform(click())
onView(withId(R.id.main_content))
.check(matches(isDisplayed()))
}
Стало (Kaspresso):
@Test
fun successfulLogin() = run {
step("Вводим email") {
LoginScreen {
emailInput.typeText("test@example.com")
}
}
step("Вводим пароль") {
LoginScreen {
passwordInput.typeText("password123")
}
}
step("Нажимаем войти") {
LoginScreen {
loginButton.click()
}
}
step("Проверяем главный экран") {
MainScreen {
mainContent.isVisible()
}
}
}
Что НЕ сделает AI (из коробки ?)
Код нужно проверять. AI сгенерирует Screen Object за 5 минут. Но он может:
Забыть импорт
Использовать deprecated API
Угадать неправильный id
Правило: каждый сгенерированный файл — запустить и проверить компиляцию. 30 секунд, которые сэкономят 30 минут отладки.
AI не знает ваш продукт. Он не понимает, что «важный клиент» = приоритет бронирования. Бизнес-логику знаете вы.
AI не найдёт все edge cases. Он предложит очевидные сценарии. Хитрые баги находят люди.
Итого: те же запросы — другой результат
Чат с DeepSeek |
Roo Code + DeepSeek |
|---|---|
часы на понимание модульной структуры |
минуты |
час на создание Screen Object |
минуты |
30 минут на каждый тест-кейс |
минуты |
Абстрактные ответы про Kaspresso |
Решение для вашего конкретного кода |
Запросы идут к тому же DeepSeek. Учитываются в ту же норму. Но вместо «кормить чат бредом» — получать реальную пользу.
Первый шаг
Не обязательно ничего внедрять или согласовывать.
Установите расширение Roo Code в VS Code
Подключите к вашему корпоративному DeepSeek (инструкция выше)
Откройте проект и спросите: «Какие модули отвечают за [фича, над которой работаете]?»
Если ответ полезен — попробуйте сгенерировать Screen Object.
Если нет — напишите в комментариях, что пошло не так.
Чек-лист промптов для QA
✅ Укажите фреймворк (Kaspresso/Espresso/Compose Testing)
✅ Ссылайтесь на существующие тесты ("в стиле LoginTest.kt")
✅ Указывайте конкретные файлы для анализа
✅ Просите решения для проблем с id
✅ Требуйте step() для читаемости
✅ Указывайте путь для сохранения файла
FAQ
Q: Запросы через Roo Code учитываются в норму?
A: Если ваша компания считает запросы к API DeepSeek — да, учитываются. Roo Code использует тот же API, просто добавляет контекст проекта к каждому запросу.
Q: Это безопасно для корпоративного кода?
A: Код не уходит наружу. Roo Code отправляет запросы на ваш локальный сервер DeepSeek — тот же, к которому вы обращаетесь через чат.
Q: Работает ли с Compose Testing?
A: Да. Укажите в промпте «Compose Testing» вместо «Kaspresso».
Q: А если проект на Java?
A: Работает. Укажите «сгенерируй на Java».
Q: Нужно ли согласовывать установку Roo Code?
A: Это расширение для VS Code, не требует админских прав. Использует тот же DeepSeek, который уже одобрен. Но если сомневаетесь — уточните у безопасников.
Вопросы и кейсы из вашей практики — в комментариях. Особенно интересны проблемы с «невидимыми» элементами в Kaspresso.