| name | testing |
| description | Пиши тесты в андроид-проекте правильно. Используй этот навык при написании любых типов тестов (unit, integration, UI), тестировании бизнес-логики и компонентов UI. |
Тестирование
When to Use
- Используй этот навык, когда пишешь unit-тесты для бизнес-логики (ViewModels, Use Cases, Domain models)
- Используй этот навык, когда пишешь интеграционные тесты для DAO и Repository
- Используй этот навык, когда пишешь UI тесты для Compose компонентов
- Используй этот навык, когда тестируешь Flow/StateFlow с использованием Turbine
- Используй этот навык, когда нужно протестировать обработку исключений в корутинах
- Этот навык полезен при выборе правильного типа теста для конкретного сценария
- Этот навык помогает определить, когда использовать unit-тесты с моками, а когда интеграционные тесты
Типы тестов
- Unit: бизнес-логика изолированно, MockK для зависимостей, AAA паттерн
- Integration: взаимодействие слоев (DAO, Repository), реальные реализации БД
- UI: критические сценарии, Compose Testing для компонентов
Инструменты
- JUnit 5 - unit-тесты
- JUnit 4 - интеграционные и UI тесты (AndroidJUnitRunner)
- MockK - мокирование
- Compose Testing - Compose компоненты
- Room Testing - для интеграционных тестов БД
- kotlinx-coroutines-test - для тестирования корутин
- Turbine - для тестирования Flow/StateFlow (app.cash.turbine:turbine)
Версии зависимостей смотри в gradle/libs.versions.toml — навык их не фиксирует.
Запуск тестов и отчеты
Команда make test
Используйте команду make test для запуска всех unit-тестов:
make test
Эта команда:
- Запускает
./gradlew test --console=plain - все unit-тесты (JVM, без устройства)
- Автоматически выполняет скрипт
scripts/test_report.py после завершения тестов
- Показывает детальный отчет со статистикой по тестовым классам
Скрипт test_report.py
Скрипт scripts/test_report.py генерирует детальный отчет о результатах тестов:
- Показывает общую статистику: всего тестов, успешные, упавшие
- Выводит список всех упавших тестов с именами классов и методов
- Отображает таблицу статистики по тестовым классам (всего, упало, успешно)
- Сортирует классы по количеству упавших тестов (по убыванию)
- Использует цвета для удобного чтения (зеленый для успеха, красный для ошибок)
- Возвращает exit code 0 если все тесты прошли, 1 если есть упавшие
Пример вывода скрипта:
================================================================================
✅ СБОРКА УСПЕШНА
================================================================================
Статистика тестов:
Всего тестов: 145
✅ Успешные: 142
❌ Упавшие: 3
❌ Список упавших тестов:
- MainScreenViewModelTest::addItem_withValidData_addsItem
- DetailScreenViewModelTest::calculateDays_whenSameDate_returnsZero
- ItemRepositoryImplTest::getAllItems_whenEmpty_returnsEmptyList
================================================================================
Статистика по тестовым классам (5 классов):
================================================================================
Класс Упало Успешно Всего
----------------------------------------------------------------------------
MainScreenViewModelTest 1 12 13
DetailScreenViewModelTest 1 8 9
ItemRepositoryImplTest 1 15 16
================================================================================
Другие команды тестирования
make android-test - запуск интеграционных тестов на Android устройстве
make android-test-report - открыть HTML отчет интеграционных тестов в браузере
Структура
app/src/test/ - unit-тесты (ViewModels, Use Cases, Domain models)
app/src/androidTest/ - integration/UI тесты (DAO, Repository, UI компоненты)
- Структура зеркалит код
- Имена классов:
*Test
Best Practices
Важно: Ограничения на интеграционные тесты с ViewModels
- ❌ Запрещено: Создавать новые интеграционные тесты с ViewModels
- ⚠️ Допустимо: Для существующих интеграционных тестов ViewModels использовать
runTest, MainDispatcherRule и Turbine
- ✅ Рекомендуется: Тестировать ViewModels только через unit-тесты с MockK
- ✅ Допустимо: Тестировать DAO и Repository через интеграционные тесты без ViewModels
- ✅ Допустимо: UI-тесты для Compose компонентов без бизнес-логики
Причина ограничений:
- Конфликт между
runBlocking и viewModelScope.launch
- Flow репозитория не активируется корректно в тестах
- Тесты зависают бесконечно или падают
- Unit-тесты с MockK обеспечивают лучшее покрытие бизнес-логики
- В JetpackDays часть интеграционных тестов ViewModels была отключена (@Ignore) из-за сложностей с асинхронностью
Рабочий подход к тестированию
Подробные примеры — в references/EXAMPLES.md. Там лежат:
- Unit-тесты ViewModels с MockK
- Интеграционные тесты DAO и Repository
- Интеграционные тесты ViewModels (только для существующих)
- UI-тесты Compose компонентов
- Тестирование Flow с исключениями
- Тестирование Use Cases
- Параметризированные тесты
- Тестирование резервного копирования
Тестирование Flow с исключениями
Важно: Для Flow с исключениями, которые обрабатываются через catch, используйте first() или collect() вместо Turbine — см. примеры в references/EXAMPLES.md.
Общие практики
- Быстрые и независимые тесты
- Описательные имена
- Один тест - одна проверка
- Тестировать поведение, не реализацию
- Интеграционные тесты только для DAO и Repository
- Unit-тесты для ViewModels с моками
- UI-тесты для Compose компонентов без бизнес-логики
- Использовать JUnit 5 аннотации (
@Test, @BeforeEach, @AfterEach)
- Использовать assertions JUnit 5 (
assertEquals, assertTrue, assertNull)