Przejdź do treści
Biblioteka skilli
Programowanie · Testowanie

flutter-testing

/flutter-testing

Pisze testy Flutter w trzech warstwach piramidy: unit, widget (testWidgets) i integration_test na symulatorze lub urządzeniu, z mockito, pokryciem LCOV i CI w Flutter Action.

Repozytorium
qa ↗
Licencja
MIT
Ostatnia zmiana repozytorium
20.10.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
2
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
1
Przestarzałość

Brak sygnałów. Repozytorium zmienione 20.10.2026, bez odwołań do wycofanych modeli i API.

Licencja

MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.

Co robi i kiedy

Pisze testy Flutter w trzech warstwach piramidy: unit, widget (testWidgets) i integration_test na symulatorze lub urządzeniu, z mockito, pokryciem LCOV i CI w Flutter Action.

Oryginalny opis (EN)

Authors Flutter tests across the three-layer pyramid - unit (`flutter test`), widget (`testWidgets` + `WidgetTester`), integration (`integration_test` on simulator/emulator/device). Picks the right layer per change, mocks via `mockito` + `build_runner`, LCOV coverage, CI with the Flutter Action. Use when the app is Flutter and the team wants its first-party stack. For React Native use detox-testing; for black-box cross-platform use appium-testing; for YAML-declarative flows use maestro-flows.

Jak działa

  1. Overview
  2. When to use
  3. Step 1 - Install
  4. Step 2 - Unit tests
  5. Step 3 - Widget tests
  6. Step 4 - Integration tests
  7. Step 5 - Mockito + buildrunner
  8. Step 6 - Coverage + reporting
  9. Step 7 - CI integration
  10. Anti-patterns
Sekcje z nagłówków SKILL.md, w oryginale · 268 linii, 886 słów
Podgląd SKILL.md
---
name: flutter-testing
description: "Authors Flutter tests across the three-layer pyramid - unit (`flutter test`), widget (`testWidgets` + `WidgetTester`), integration (`integration_test` on simulator/emulator/device). Picks the right layer per change, mocks via `mockito` + `build_runner`, LCOV coverage, CI with the Flutter Action. Use when the app is Flutter and the team wants its first-party stack. For React Native use detox-testing; for black-box cross-platform use appium-testing; for YAML-declarative flows use maestro-flows."
---

# flutter-testing

## Overview

Per [flutter-testing-doc][ft]:

[ft]: https://docs.flutter.dev/testing/overview

> "Flutter uses a **testing pyramid** approach with three main
> categories":
>
> 1. **Unit Tests** - single function / method / class; mocked
>    dependencies; quick.
> 2. **Widget Tests** - single widget; UI + lifecycle + interactions;
>    quick.
> 3. **Integration Tests** - full app or large sections; on real
>    devices/emulators; highest confidence; slowest.

The framework ships first-party tooling for all three layers.

## When to use

- The app is Flutter (the framework's intended use case).
- The team uses Dart and wants test-stack consistency with
  production code.

## Step 1 - Install

Flutter ships with `flutter_test` (in the SDK). For mocks:

```yaml
# pubspec.yaml
dev_dependencies:
  flutter_test:
    sdk: flutter
  integration_test:
    sdk: flutter
  mockito: ^5.4.4
  build_runner: ^2.4.13
```

## Step 2 - Unit tests

Pure-Dart functions with mocked dependencies:

```dart
// test/cart_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:my_app/cart.dart';

void main() {
  group('Cart', () {
    test('addItem increments count', () {
      final cart = Cart();
      cart.addItem(Item(sku: 'BOOK-001', qty: 1));
      expect(cart.itemCount, 1);
    });

    test('addItem rejects negative qty', () {
      final cart = Cart();
      expect(
        () => cart.addItem(Item(sku: 'BOOK-001', qty: -1)),
        throwsA(isA<ArgumentError>()),
      );
    });
  });
}
```

Run:

```bash
flutter test test/cart_test.dart
flutter test                       # all tests
flutter test --coverage            # produces coverage/lcov.info
```

The LCOV output feeds `lcov-analysis` (in the qa-test-reporting plugin).

## Step 3 - Widget tests

Per [flutter-testing-doc][ft], widget tests "verify the UI looks
and interacts as expected":

```dart
// test/cart_screen_test.dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:my_app/cart_screen.dart';

void main() {
  testWidgets('CartScreen shows item count', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(home: CartScreen(initialCount: 3)));

    expect(find.text('3 items'), findsOneWidget);
    expect(find.byKey(Key('add-to-cart-button')), findsOneWidget);
  });

  testWidgets('Tapping add button increments count', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(home: CartScreen(initialCount: 0)));

    await tester.tap(find.byKey(Key('add-to-cart-button')));
    await tester.pump();   // rebuild after state change

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

`tester.pumpWidget(...)` mounts the widget tree. `tester.pump()`
advances the frame; `tester.pumpAndSettle()` advances until no
animations are pending.

Finders:

| Finder                | Use                                              |
|-----------------------|--------------------------------------------------|
| `find.byKey(Key(...))` | By Key (preferred for stable lookups).            |
| `find.text("...")`     | By visible text (translation-fragile).            |
| `find.byType(Widget)`  | By widget type.                                   |
| `find.byIcon(Icons.x)` | By Material icon.                                 |
| `find.descendant(of:, matching:)` | Nested matching.                       |

## Step 4 - Integration tests

Per [flutter-testing-doc][ft], integration tests "test complete app
or large app sections" on real devices.

```dart
// integration_test/checkout_flow_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:my_app/main.dart' as app;

void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

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

    await tester.tap(find.byKey(Key('login-button')));
    await tester.pumpAndSettle();

    await tester.enterText(find.byKey(Key('email-field')), 'qa-test@example.com');
    // ... etc.
  });
}
```

Run:

```bash
# On a connected device or simulator/emulator
flutter test integration_test/checkout_flow_test.dart
```

## Step 5 - Mockito + build_runner

For mocks:

```dart
// test/cart_test.dart
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'cart_test.mocks.dart';   // generated

@GenerateMocks([CartRepo])
void main() {
  test('Cart loads from repo', () async {
    final mockRepo = MockCartRepo();
    when(mockRepo.getCart()).thenAnswer(
      (_) async => Cart(items: [Item(sku: 'BOOK-001', qty: 1)]),
    );

    final cart = await mockRepo.getCart();
    expect(cart.itemCount, 1);
    verify(mockRepo.getCart()).called(1);
  });
}
```

Generate the `*.mocks.dart` files:

```bash
dart run build_runner build --delete-conflicting-outputs
```

## Step 6 - Coverage + reporting

```bash
flutter test --coverage           # writes coverage/lcov.info
genhtml coverage/lcov.info -o coverage/html   # human report
```

The LCOV file feeds the same parser other plugins use
(`lcov-analysis`)
for cross-language coverage aggregation.

## Step 7 - CI integration

```yaml
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: subosito/flutter-action@v2
        with:
          channel: stable
      - run: flutter pub get
      - run: dart run build_runner build --delete-conflicting-outputs
      - run: flutter test --coverage
      - uses: codecov/codecov-action@v5
        with:
          files: coverage/lcov.info

  integration-android:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: subosito/flutter-action@v2
      - uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: 34
          script: flutter test integration_test/
```

Per [flutter-testing-doc][ft], Flutter supports CI integration via
"Fastlane / Travis CI / Cirrus CI / Codemagic / Bitrise / Appcircle /
Patrol (for native platform interactions)."

## Anti-patterns

| Anti-pattern                                                         | Why it fails                                                              | Fix |
|----------------------------------------------------------------------|---------------------------------------------------------------------------|-----|
| All tests as integration tests                                        | Slow; fragile; hides per-layer issues per the pyramid.                    | Many unit + widget; few integration (Step 1 pyramid). |
| `find.text("...")` for translatable strings                           | Translation breaks tests.                                                  | `find.byKey(Key("..."))` (Step 3). |
| `tester.pump()` (single frame) for animations                         | Animation isn't done; assertion fires too early.                          | `tester.pumpAndSettle()` for animations. |
| Skipping `IntegrationTestWidgetsFlutterBinding.ensureInitialized()`   | Integration test won't bind; runtime errors.                              | Add as first line in main() (Step 4). |
| Mock without `@GenerateMocks` (manual mock classes)                    | Tedious; drift when the SUT interface changes.                            | Use `@GenerateMocks` + `build_runner` (Step 5). |
| Coverage from integration tests only                                  | Integration coverage is sparse; misses unit-level branches.               | Coverage from `flutter test` (which runs unit + widget). |

## Limitations

- **`flutter drive` deprecated for new projects.** Use
  `integration_test` package (modern; Step 4).
- **Native platform features need extra packages.** For things like
  permissions / camera / push notifications, use `patrol` or
  per-platform native integration.
- **Widget tests use a fake `Stub` for `MediaQuery` etc.** Surface
  varies vs production; widget tests don't cover layout/font issues
  that need a real renderer.
- **Mockito's null safety story.** Generation handles it; manual
  mocks are awkward.

## References

- [ft][ft] - Flutter testing pyramid: unit / widget / integration;
  trade-off matrix (confidence, maintenance, deps, speed); CI
  integration list; `flutter test` / `flutter drive` commands.
- `xcuitest-suite`,
  `espresso-suite`,
  `detox-testing` - alternative
  framework wrappers when the app isn't Flutter.
- `lcov-analysis` - downstream consumer of `flutter test --coverage`.
Pliki w paczce (2)
  • SKILL.md 9 KB
  • .tessl-plugin/plugin.json 1 KB

Wersje

RepozytoriumWynikLicencja
Ta strona · testland/qa100MIT
HoangNguyen0403/agent-skills-standard100MIT
thiennc-tesoglobal/flutter-skills100BSD-3-Clause
ethiel97/flutter-clean-riverpod-skills100MIT
jyotiraditya-chauhan/test-kit100MIT
madteacher/mad-agents-skills100MIT
dhruvanbhalara/skills90MIT

Migawka bazy z 28.10.2026 · wersja paczki df9313d505e6 (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 100detox-testing
    Pisze testy E2E React Native w Detox (Wix) w architekturze gray-box: matchery by.id, by.text i by.label, jawne waitFor() ponad automatyczną synchronizacją i runner Jest.
  • 100flutter-device-testing
    Obsługuje i weryfikuje aplikacje Flutter na konkretnym emulatorze, symulatorze, przeglądarce, desktopie lub urządzeniu: cykl życia celu, sprawdzenia stanu platformy i przepływy integracyjne na żywo.
  • 100detox
    Pomaga konfigurować Detox, framework testów end-to-end gray-box dla React Native, pisać i naprawiać testy oraz uruchamiać je w CI na symulatorze iOS lub emulatorze Androida.
  • 100flutter-device-testing
    Obsługuje i weryfikuje aplikacje Flutter na konkretnym emulatorze, symulatorze, przeglądarce, desktopie lub urządzeniu fizycznym: cykl życia celu, stan platformy, dowody z działania i przepływy integracyjne na żywo.
  • 85flutter-core:flutter-testing-quality
    Pisze testy aplikacji Flutter: jednostkowe, widgetów, integracyjne i golden, z mockami, pokryciem i profilowaniem w DevTools.
  • 100flutter-test-strategy
    Pomaga zdecydować, co testować w kodzie Flutter i Dart na której warstwie (unit, widget, golden, integration) oraz ustawić progi pokrycia.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.