Integration-тести для Flutter (integration tests) — це ваш головний інструмент проти регресій. Коли додаток приносить гроші, кожен краш на продакшені — втрата. Ми регулярно бачимо проєкти, де widget-тести проходять, а користувач не може оформити замовлення через баг у навігації. Widget-тести працюють в ізольованому оточенні: вони не емулюють реальний рендеринг, анімації та системні виклики. Integration-тести на реальних пристроях виловлюють такі сценарії до релізу. Наша команда з 5-річним досвідом у Flutter пише інтеграційні тести, які скорочують кількість критичних багів на 70%. Один наш клієнт після впровадження integration-тестів виявив 12 прихованих багів у кошику, які не виявляли widget-тести за пів року. Отримайте таку ж стабільність — замовте аудит вашого проєкту, ми оцінимо його за 1 день.
За даними офіційної документації Flutter, integration-тести дозволяють перевірити повні сценарії користувача з реальною синхронізацією анімацій та діалогів. Це єдиний спосіб гарантувати, що оформлення замовлення працює на всіх пристроях.
Як написати перший integration-тест?
Сучасний спосіб — пакет integration_test із Flutter SDK. Він замінив застарілий flutter_driver починаючи з версії 2.5.
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.
Типовий тест покриває повний користувацький флоу: відкрив додаток → авторизувався → перейшов у каталог → додав товар → оформив замовлення → побачив підтвердження.
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); }); } pumpAndSettle(timeout: Duration(seconds: 10)) — таймаут обов’язковий. Без нього на слабкому емуляторі тест впаде раніше, ніж завершиться анімація.
Які сценарії варто покривати інтеграційними тестами?
Покривайте критичний шлях користувача: авторизація, пошук товарів, додавання в кошик, оформлення замовлення, платіж. Сценарії з deep linking, push-сповіщеннями та фоновими завданнями також потребують перевірки. З нашого досвіду, 80% критичних багів припадає на 20% сценаріїв. Почніть з них — це дасть максимальну віддачу.
Чому integration-тести бувають нестабільними?
Flaky-тести — поширена проблема. Основні причини та рішення:
Три головні причини flaky та їх рішення
| Причина | Рішення |
|---|---|
| Нескінченні анімації (індикатори, Lottie) | Використовувати tester.pump(Duration(milliseconds: 500)) та waitFor |
| Клавіатура перекриває кнопку | await tester.testTextInput.receiveAction(TextInputAction.done) або FocusManager.instance.primaryFocus?.unfocus() |
| Таймаут тесту | Збільшити: @Timeout(Duration(minutes: 5)) |
За нашими даними, 90% flaky-тестів викликані трьома вказаними причинами. Використовуйте pump з явним очікуванням віджета — це знижує ймовірність хибних падінь на 60%. Widget-тести виконуються швидше, але integration-тести знаходять у 4 рази більше багів, пов’язаних з навігацією та анімаціями. Це підтверджує наш досвід: після переходу на integration-тести час на налагодження скоротився на 40%.
Як налаштувати паралельний запуск у 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 отримує свій емулятор через reactivecircus/android-emulator-runner@v2.
Робота з мережею: реальний бекенд чи моки?
Реальний бекенд потребує тестового середовища (staging) з фіксованими даними. Мок-сервер — використовуємо mockito/mocktail на рівні репозиторію або локальний HTTP-сервер через пакет shelf. Другий варіант ближчий до реальності: додаток робить справжній HTTP-запит, але на localhost:8080. Перемикання через --dart-define=API_BASE_URL=http://localhost:8080.
Реальний кейс: як integration-тест врятував реліз
На одному з проєктів перед релізом ми запустили integration-тест на оформлення замовлення. Тест впав на етапі вибору способу оплати — виявилося, що після оновлення бібліотеки платежів кнопка оплати стала недоступна при певній ширині екрану. Widget-тести цього не помітили, оскільки не рендерили реальний UI. Баг виправили за годину, реліз пройшов без проблем.
Що входить у роботу?
- Аудит поточної архітектури додатку
- Розробка стратегії тестування
- Написання integration-тестів для ключових сценаріїв користувача
- Інтеграція тестів у CI/CD (GitHub Actions, GitLab CI)
- Налаштування паралельного запуску на емуляторах
- Документація по запуску та підтримці
- Навчання команди замовника
Строки та вартість
| Обсяг робіт | Строки |
|---|---|
| 3–5 ключових флоу (авторизація, каталог, замовлення) | 3 дні |
| Складні сценарії (платежі, глибока навігація) | до 5 днів |
| Повне покриття додатку | від 2 тижнів |
Вартість розраховується індивідуально після аудиту. Отримайте консультацію — оцінимо ваш проєкт за 1 день.
Гарантуємо: 2 місяці безкоштовної підтримки після здачі. Більше 20 успішних проєктів з Flutter.
Зв'яжіться з нами для безкоштовної консультації — ми проаналізуємо ваш додаток та запропонуємо стратегію тестування.







