# Unit, Widget and Integration Tests — Flutter

Source: https://www.skillbyai.com/en/flutter/p-testing

> The Flutter testing pyramid.

## Three kinds of tests

**Unit tests** check plain Dart logic (models, parsers, notifiers) with `test` and `expect`. **Widget tests** (package flutter_test) render widgets in a fast headless environment: `testWidgets` gives a `WidgetTester` to `pumpWidget`, find widgets with `find.text`, `find.byType` or `find.byKey`, interact with `tap` and `enterText`, then call `pump()` (one frame) or `pumpAndSettle()` (until animations finish) before asserting with matchers such as `findsOneWidget`. **Integration tests** (package integration_test) run the whole app on a real device or emulator. Run tests with `flutter test`; fake network and storage dependencies with mocks (mocktail or mockito) or provider overrides.

## Ship with confidence

Tests catch regressions, profiling keeps frames smooth, and a repeatable build pipeline gets the app to the stores.

![Four ideas: testing, performance, building and releasing, a final checklist.](assets/figures/flutter/section-8-map.svg) — Figure 8.1 — Test, profile, build, release.

## A widget test for the counter

Pump, tap, pump, expect.

```dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:my_app/counter.dart';

void main() {
  test('Cart adds items', () {
    final cart = Cart();
    cart.add(const Item('Tea'));
    expect(cart.count, 1);
  });

  testWidgets('tapping + increments the counter', (tester) async {
    await tester.pumpWidget(const MaterialApp(home: Scaffold(body: Counter())));

    expect(find.text('Count: 0'), findsOneWidget);

    await tester.tap(find.byIcon(Icons.add));
    await tester.pump(); // rebuild after setState

    expect(find.text('Count: 1'), findsOneWidget);
  });
}
```

## Golden tests for visuals

matchesGoldenFile compares a widget's rendering with a stored image; regenerate goldens with flutter test --update-goldens when a change is intentional.

**Quiz:** In a widget test, what must you call after tapping a button that calls setState?

- [ ] Nothing; the UI updates instantly
- [ ] flutter run
- [ ] tester.dispose()
- [x] tester.pump() to build the next frame

*Answer:* tester.pump() to build the next frame. The test environment only rebuilds when you pump frames.
