ホーム/移动开发/flutter-testing
F

flutter-testing

by @flutterv
4.6(15)

Flutterアプリケーションの自動テストを生成、設定、デバッグし、ユニット、ウィジェット、統合、およびプラグインテストをカバーします。

FlutterWidget TestingIntegration TestingUnit TestingTest AutomationGitHub
インストール方法
npx skills add flutter/skills --skill flutter-testing
compare_arrows

Before / After 効果比較

1
使用前

以前は、Flutterアプリケーションのテストは主に手動操作に依存しており、時間と労力がかかり、問題を見落としがちでした。単体テストのカバレッジが低く、コンポーネントテストや統合テストが不十分だったため、潜在的な欠陥を発見することが難しく、リリース後に頻繁にバグが発生し、開発効率とユーザーの信頼を著しく損なっていました。

使用後

現在、私たちはFlutterアプリケーション向けに、単体、コンポーネント、統合、プラグインテストを含む包括的な自動テストを生成および設定できます。効率的なデバッグツールを使用することで、問題を迅速に特定して修正し、コード品質とアプリケーションの安定性を確保します。これにより、開発サイクルが大幅に短縮され、リリースへの自信が高まり、ユーザーにより信頼性の高い体験を提供できます。

description SKILL.md

flutter-testing

flutter-automated-testing

Goal

Generates, configures, and debugs automated tests for Flutter applications, encompassing unit, widget, integration, and plugin testing. Analyzes architectural components (such as MVVM layers) to produce isolated, mock-driven tests and end-to-end device tests. Assumes a standard Flutter project structure, existing business logic, and familiarity with Dart testing paradigms.

Instructions

1. Determine Test Type (Decision Logic)

Evaluate the user's target code to determine the appropriate testing strategy using the following decision tree:

  • If verifying a single function, method, ViewModel, or Repository: Implement a Unit Test (Proceed to Step 2).

  • If verifying a single widget's UI, layout, or interaction: Implement a Widget Test (Proceed to Step 3).

  • If verifying complete app behavior, routing, or performance on a device: Implement an Integration Test (Proceed to Step 4).

  • If verifying platform-specific native code (MethodChannels): Implement a Plugin Test (Proceed to Step 5).

STOP AND ASK THE USER: "Which specific class, widget, or flow are we testing today? Please provide the relevant source code if you haven't already."

2. Implement Unit Tests (Logic & Architecture)

Unit tests verify logic without rendering UI. They must reside in the test/ directory and end with _test.dart.

  • For ViewModels (UI Layer Logic): Fake the repository dependencies. Do not rely on Flutter UI libraries.
import 'package:test/test.dart';
// Import your ViewModel and Fakes here

void main() {
  group('HomeViewModel tests', () {
    test('Load bookings successfully', () {
      final viewModel = HomeViewModel(
        bookingRepository: FakeBookingRepository()..createBooking(kBooking),
        userRepository: FakeUserRepository(),
      );

      expect(viewModel.bookings.isNotEmpty, true);
    });
  });
}

  • For Repositories (Data Layer Logic): Fake the API clients or local database services.
import 'package:test/test.dart';
// Import your Repository and Fakes here

void main() {
  group('BookingRepositoryRemote tests', () {
    late BookingRepository bookingRepository;
    late FakeApiClient fakeApiClient;

    setUp(() {
      fakeApiClient = FakeApiClient();
      bookingRepository = BookingRepositoryRemote(apiClient: fakeApiClient);
    });

    test('should get booking', () async {
      final result = await bookingRepository.getBooking(0);
      final booking = result.asOk.value;
      expect(booking, kBooking);
    });
  });
}

3. Implement Widget Tests (UI Components)

Widget tests verify UI rendering and interaction. They must reside in the test/ directory and use the flutter_test package.

  • Use WidgetTester to build the widget.

  • Use Finder to locate elements (find.text(), find.byKey(), find.byWidget()).

  • Use Matcher to verify existence (findsOneWidget, findsNothing, findsNWidgets).

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('HomeScreen displays title and handles tap', (WidgetTester tester) async {
    // 1. Setup Fakes and ViewModel
    final bookingRepository = FakeBookingRepository()..createBooking(kBooking);
    final viewModel = HomeViewModel(
      bookingRepository: bookingRepository,
      userRepository: FakeUserRepository(),
    );

    // 2. Build the Widget tree
    await tester.pumpWidget(
      MaterialApp(
        home: HomeScreen(viewModel: viewModel),
      ),
    );

    // 3. Finders
    final titleFinder = find.text('Home');
    final buttonFinder = find.byKey(const Key('increment_button'));

    // 4. Assertions
    expect(titleFinder, findsOneWidget);

    // 5. Interactions
    await tester.tap(buttonFinder);
    await tester.pumpAndSettle(); // Wait for animations/state updates to finish

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

4. Implement Integration Tests (End-to-End)

Integration tests run on real devices or emulators. They must reside in the integration_test/ directory.

  • Ensure integration_test is in dev_dependencies in pubspec.yaml.

  • Initialize IntegrationTestWidgetsFlutterBinding.

import 'package:flutter/material.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();

  group('End-to-End App Test', () {
    testWidgets('Full flow: tap FAB and verify counter', (WidgetTester tester) async {
      // Load the full app
      app.main();
      await tester.pumpAndSettle();

      // Verify initial state
      expect(find.text('0'), findsOneWidget);

      // Find and tap the FAB
      final fab = find.byKey(const ValueKey('increment'));
      await tester.tap(fab);
      
      // Trigger a frame
      await tester.pumpAndSettle();

      // Verify state change
      expect(find.text('1'), findsOneWidget);
    });
  });
}

5. Implement Plugin Tests (Native & Dart)

If testing a plugin, tests must cover both Dart and Native communication.

  • Dart Side: Mock the platform channel and call the plugin's public API.

  • Native Side: Instruct the user to write native tests in the respective directories:

Android: android/src/test/ (JUnit)

  • iOS/macOS: example/ios/RunnerTests/ (XCTest)

  • Linux/Windows: linux/test/ (GoogleTest)

6. Validate and Fix (Feedback Loop)

Provide the user with the exact command to run the generated test:

  • Unit/Widget: flutter test test/your_test_file.dart

  • Integration: flutter test integration_test/your_test_file.dart

STOP AND ASK THE USER: "Please run the test using the command above and paste the output. If the test fails, provide the stack trace so I can analyze the failure and generate a fix."

Constraints

  • Single Source of Truth: Do not duplicate state in tests. Always use fakes or mocks for external dependencies (Repositories, Services) to isolate the unit under test.

  • No Logic in Widgets: When writing widget tests, assume the widget is "dumb". All business logic should be tested via the ViewModel/Controller unit tests.

  • File Naming: All test files MUST end with _test.dart.

  • Pump vs PumpAndSettle: Use tester.pump() for single frame advances. Use tester.pumpAndSettle() strictly when waiting for animations or asynchronous UI updates to complete.

  • Immutability: Treat test data models as immutable. Create new instances for state changes rather than mutating existing mock data.

  • Do not use dart:mirrors: Flutter does not support reflection. Rely on code generation (e.g., build_runner, mockito, mocktail) for mocking.

Weekly Installs1.0KRepositoryflutter/skillsGitHub Stars725First Seen14 days agoSecurity AuditsGen Agent Trust HubPassSocketPassSnykPassInstalled oncodex981github-copilot977opencode977cursor977gemini-cli976kimi-cli975

forumユーザーレビュー (0)

レビューを書く

効果
使いやすさ
ドキュメント
互換性

レビューなし

統計データ

インストール数691
評価4.6 / 5.0
バージョン
更新日2026年3月17日
比較事例1 件

ユーザー評価

4.6(15)
5
0%
4
0%
3
0%
2
0%
1
0%

この Skill を評価

0.0

対応プラットフォーム

🔧Claude Code
🔧OpenClaw
🔧OpenCode
🔧Codex
🔧Gemini CLI
🔧GitHub Copilot
🔧Amp
🔧Kimi CLI

タイムライン

作成2026年3月17日
最終更新2026年3月17日