Skip to content

Flutter Testing Best Practices

(c) Написано с использованием нейросетей ChatGPT 5

Краткий список best practices для Flutter-тестов, чтобы писать стабильные и поддерживаемые тесты.

1. Пиши маленькие, атомарные тесты

  • Каждый тест должен проверять одну вещь.
  • Легче отлаживать и понимать, что сломалось.
  • Например, проверка только текста, или только вызова метода, не всё вместе.

2. Используй ключи для поиска виджетов

  • ValueKey или UniqueKey упрощают поиск конкретных элементов.
  • Особенно важно при нескольких одинаковых виджетах.
  • Пример:
dart
FFTIconButton.standard(key: ValueKey('close-button'))

3. Для виджетов используйте find.byType и WidgetPredicate

  • byType для общего поиска виджетов по типу.
  • byWidgetPredicate — когда виджет создаётся через приватный класс/factory.
  • byWidget почти не используют — ищет конкретный экземпляр.

4. Всегда вызывай pump() или pumpAndSettle() после изменения состояния

  • pump() — один кадр, обновляет дерево виджетов.
  • pumpAndSettle() — ждёт окончания анимаций и микротасков.
  • Без этого тест не увидит изменения.

5. Мокируй внешние зависимости

  • API, база данных, SharedPreferences и т.д. должны быть моками.
  • Используй mocktail или mockito.
  • Проверяй не только результат, но и вызовы методов на моках.

6. Проверяй анимации и видимость

  • Для виджетов с анимацией/opacity используйте pumpAndSettle().
  • Для элементов, которые могут игнорировать события (IgnorePointer), проверяйте их состояние перед взаимодействием.
  • Используйте warnIfMissed: false, если тап не должен проходить.

7. Разделяй синхронные и асинхронные тесты

  • Асинхронные тесты должны быть async и использовать await.
  • Для Stream используйте expectLater.
  • Не смешивайте синхронные и асинхронные проверки в одном тесте без await.

8. Используй setUp и tearDown

  • Для подготовки состояния перед тестом и очистки после.
  • setUpAll / tearDownAll — один раз на группу тестов.
  • Избегает дублирования кода и ошибок при инициализации.

9. Проверяй ожидаемые исключения

dart
expect(() => functionThatThrows(), throwsA(isA<FormatException>()));
  • Всегда указывай тип исключения, если возможно.
  • Это предотвращает ложноположительные тесты.

10. Документируй и комментируй тесты

  • Название testWidgets или test должно быть понятным и описательным.
  • Добавляйте комментарии, если есть нюансы (например, warnIfMissed: false).
  • Позволяет быстрее понять цель теста через месяц/год.

Дополнительно

  • Используйте ключи и finders последовательно в проекте.
  • Старайтесь избегать sleep() и таймеров в тестах.
  • Проверяйте не только результат, но и состояние дерева виджетов.
  • Разделяйте unit и widget тесты для лучшей читаемости и стабильности.