Разработка Integration-тестов для Flutter-приложения

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Разработка Integration-тестов для Flutter-приложения
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    445

Разработка Integration-тестов для Flutter-приложения

Integration-тесты во Flutter запускаются на реальном устройстве или эмуляторе. Приложение стартует полностью: движок Dart, Flutter Framework, ваш код. WidgetTester здесь работает поверх настоящего рендеринга, а не синтетического. Именно поэтому integration-тесты находят то, что widget-тесты пропускают: проблемы с навигацией между реальными Route, тайминги анимаций на конкретном железе, поведение при низкой памяти.

Пакет integration_test

Современный способ — пакет integration_test из Flutter SDK (не сторонний, официальный с Flutter 2.5). Он заменил устаревший flutter_driver.

pubspec.yaml:

dev_dependencies:
  integration_test:
    sdk: flutter
  flutter_test:
    sdk: flutter

Структура директорий:

integration_test/
  app_test.dart
test_driver/
  integration_test.dart  # только для запуска через flutter drive

Запуск на подключённом устройстве:

flutter test integration_test/app_test.dart

Запуск в Firebase Test Lab или BrowserStack — через flutter build apk --target integration_test/app_test.dart + загрузка APK.

Что тестируем и как

Типичный integration-тест покрывает полный пользовательский флоу: открыл приложение → авторизовался → перешёл на экран каталога → добавил товар в корзину → оформил заказ → увидел экран подтверждения.

void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

  testWidgets('Full checkout flow', (tester) async {
    app.main();
    await tester.pumpAndSettle();

    // Логин
    await tester.enterText(find.byKey(Key('email')), '[email protected]');
    await tester.enterText(find.byKey(Key('password')), 'password123');
    await tester.tap(find.byKey(Key('login_btn')));
    await tester.pumpAndSettle(timeout: Duration(seconds: 10));

    expect(find.byKey(Key('home_screen')), findsOneWidget);

    // Добавление в корзину
    await tester.tap(find.byKey(Key('product_card_1')));
    await tester.pumpAndSettle();
    await tester.tap(find.byKey(Key('add_to_cart_btn')));
    await tester.pumpAndSettle();

    expect(find.text('1'), findsOneWidget); // badge на иконке корзины
  });
}

pumpAndSettle(timeout: Duration(seconds: 10)) — таймаут нужен. Без него на слабом эмуляторе тест упадёт раньше, чем анимация навигации завершится.

Параллельный запуск

Один тест-файл — одна сессия устройства. Для параллельного прогона создаём несколько файлов и запускаем их через матрицу в CI. В GitHub Actions:

strategy:
  matrix:
    test-file: [auth_test.dart, checkout_test.dart, profile_test.dart]
steps:
  - run: flutter test integration_test/${{ matrix.test-file }}

Каждый job получает свой эмулятор. AVD Manager через reactivecircus/android-emulator-runner@v2 запускает их параллельно.

Работа с реальными сетевыми запросами

Здесь главный выбор: тестировать против реального бэкенда или мокировать сеть.

Реальный бэкенд — нужна тестовая среда (staging). Данные должны быть предсказуемы: фиксированные тестовые аккаунты, детерминированные ответы. Сетевые ошибки делают тесты нестабильными.

Мок-серверmockito/mocktail на уровне репозитория, или локальный HTTP-сервер через пакет shelf. Второй вариант ближе к реальности: приложение делает настоящий HTTP-запрос, но на localhost:8080 вместо api.production.com. Переключение через переменную окружения или --dart-define=API_BASE_URL=http://localhost:8080.

Нестабильность integration-тестов

Flaky-тесты в integration_test — распространённая проблема. Основные причины:

Анимации. pumpAndSettle() ждёт их завершения, но если в приложении есть бесконечная анимация (индикатор загрузки, lottie-анимация в фоне), pumpAndSettle() зависнет. Решение: tester.pump(Duration(milliseconds: 500)) с явным ожиданием конкретного виджета через waitFor.

Клавиатура. После enterText() системная клавиатура может перекрывать кнопку. Прячем: await tester.testTextInput.receiveAction(TextInputAction.done) или FocusManager.instance.primaryFocus?.unfocus() перед tap().

Таймаут теста. По умолчанию integration-тест завершается через 10 минут. Для длинных флоу увеличиваем: @Timeout(Duration(minutes: 5)) над testWidgets.

Сроки

3–5 дней для написания integration-тестов к существующему приложению. Сложный флоу с авторизацией, платежами и глубокой навигацией — ближе к 5 дням. Простые линейные сценарии — 3 дня. Стоимость рассчитывается после аудита архитектуры приложения.