Что использовал для написания widget-тестов во Flutter?

Ответ

Для widget-тестов я использую встроенный пакет flutter_test. Его ключевые инструменты:

  • testWidgets(): Функция для объявления теста.
  • WidgetTester: Предоставляет методы для рендеринга виджетов (pumpWidget), взаимодействия с ними (tap, enterText) и управления временем (pumpAndSettle).
  • Finder: Для поиска виджетов в дереве (find.text(), find.byKey(), find.byType()).
  • Matcher: Для проверок (findsOneWidget, findsNothing, findsNWidgets).

Пример теста кнопки-счётчика из моего проекта:

import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('Counter increments when + button is pressed', (tester) async {
    // 1. Рендерим виджет
    await tester.pumpWidget(const MyApp());

    // 2. Проверяем начальное состояние
    expect(find.text('0'), findsOneWidget);
    expect(find.text('1'), findsNothing);

    // 3. Имитируем действие пользователя
    await tester.tap(find.byIcon(Icons.add));
    await tester.pump(); // Триггерим перестроение

    // 4. Проверяем результат
    expect(find.text('0'), findsNothing);
    expect(find.text('1'), findsOneWidget);
  });
}

Дополнительные инструменты в моём стеке:

  • mocktail: Для создания моков (предпочитаю его mockito, так как не требует генерации кода).
  • bloc_test: Для тестирования BLoC/Cubit (интегрируется с flutter_test).
  • golden_toolkit: Для golden-тестов (сравнения скриншотов).

Ключевая практика — это изоляция тестов: использование setUp для подготовки моков и setUpWidgetTester для кастомизации среды (например, размера экрана).

Ответ 18+ 🔞

А, ну вот, зашёл разговор про тестирование виджетов во Flutter! Давай я тебе на пальцах объясню, как тут всё устроено, а то документация иногда читается, как инструкция к шаманскому бубну.

Так вот, основной инструмент, без которого нихуя не сделаешь — это встроенный пакет flutter_test. Не надо ничего качать отдельно, он уже в коробке. Главные герои в этой истории:

  • testWidgets() — это типа объявить: "Сейчас, блядь, будем тестировать!" Функция такая.
  • WidgetTester — вот это вообще золото. Этот чувак умеет всё: и виджет на экран вывалить (pumpWidget), и по нему тыкать (tap), и текст вводить (enterText). А ещё время управлять может (pumpAndSettle), что иногда овердохуища важно.
  • Finder — искатель, шерлок холмс. Его задача найти в этом дереве виджетов нужную хрень: по тексту (find.text()), по ключу (find.byKey()), по типу (find.byType()).
  • Matcher — проверяльщик. После того как нашёл, надо убедиться, что это оно. findsOneWidget — один нашёлся, findsNothing — нихуя не нашлось, findsNWidgets — нашлось, блядь, сколько надо.

Смотри, вот живой пример из моего проекта, кнопка-счётчик, классика жанра:

import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('Counter increments when + button is pressed', (tester) async {
    // 1. Сначала вываливаем наш виджет на экран. Без этого нихуя не увидишь.
    await tester.pumpWidget(const MyApp());

    // 2. Проверяем, что всё стартует с нуля. Доверия-то ебать ноль, надо проверять.
    expect(find.text('0'), findsOneWidget);
    expect(find.text('1'), findsNothing);

    // 3. Эмулируем, что юзер, этот распиздяй, тыкнул на плюсик.
    await tester.tap(find.byIcon(Icons.add));
    await tester.pump(); // Это чтобы флаттер перестроил интерфейс, а то зависнуть может.

    // 4. Смотрим, что получилось. Если вместо 1 всё ещё 0 — пидарас шерстяной, где-то косяк.
    expect(find.text('0'), findsNothing);
    expect(find.text('1'), findsOneWidget);
  });
}

Ну а кроме этого базового набора, у меня в арсенале ещё парочка приблуд, чтобы жизнь мёдом не казалась:

  • mocktail — для создания фейков, заглушек. Я его предпочитаю старому mockito, потому что не надо нихрена генерировать код, всё сразу пишется. Удобно, ёпта.
  • bloc_test — если юзаешь BLoC или Cubit, то это святое. Он с flutter_test за ручку ходит, всё красиво интегрируется.
  • golden_toolkit — это уже для параноиков, которые хотят сравнивать скриншоты. Golden-тесты, называется. Чтобы случайно тень не съехала на пиксель и дизайнер не пришёл с вилкой.

И главное правило, которое я усвоил, — изоляция. Каждый тест должен жить своей жизнью. Для этого есть setUp, где ты подготавливаешь все свои моки, и setUpWidgetTester, где можно, например, размер экрана выставить, чтобы не зависеть от девайса. Иначе получится такая каша, что сам от себя охуеешь.