Skip to main content
skill Claude Code CX Codex Cursor GitHub Copilot

flutter-add-widget-test — Claude Code skill: Flutter widget testing

A skill that teaches AI coders to write component-level Flutter tests using WidgetTester. Verifies how widgets render and respond to taps, scrolling, and text input.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add flutter/agent-plugins --skill flutter-add-widget-test -a claude-code
Open on GitHub

What flutter-add-widget-test does

flutter-add-widget-test guides the AI through flutter_test patterns: using Finder to locate widgets, Matcher to verify state, and the sequence of tester.tap(), tester.enterText(), tester.pump(), and tester.pumpAndSettle() calls.

It includes a full example: wrapping a widget in MaterialApp for inherited theme data, simulating gestures and text entry, waiting for animations to finish. The skill covers when to use pump() for a single frame rebuild and when to use pumpAndSettle() to let transitions complete.

You need flutter_test in dev_dependencies and test files in the test/ directory named with _test.dart suffix. The skill targets developers who write UI tests for Flutter apps.

What it helps with

  • write a test that verifies a widget renders with the correct data
  • test how a widget responds to taps and text input
  • confirm an animation or transition finished before checking state
  • find an element in the widget tree by type, text, or key
  • test deletion of an item or list changes

Example prompts for the agent

  • Write a test for my Counter widget that verifies the button increments the number by 1
  • Create a test for TodoList: add an item through TextField, check it appears, then remove it with a swipe
  • Write a widget test for a login screen: enter email and password, tap the button, wait for animation, verify no error text appears

How to install flutter-add-widget-test

1Skills CLI (Vercel)

npx skills add flutter/agent-plugins --skill flutter-add-widget-test -a claude-code

2Manually: put the files in place

~/.claude/skills/flutter-add-widget-test/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/flutter-add-widget-test/

From the same set14

The whole set →
flutter-apply-architecture-best-practices flutter This skill structures Flutter apps around UI, Logic, and Data layers. Use it when starting a project or refactoring code for scale. Claude Code CX Codex Cursor +1 43,000installs flutter-build-responsive-layout flutter This skill guides coding agents to build adaptive Flutter UIs across mobile and desktop screens using LayoutBuilder and BoxConstraints. Claude Code CX Codex Cursor +1 42,300installs flutter-add-integration-test flutter Sets up the integration_test package for Flutter and turns MCP session interactions into repeatable end-to-end tests. Claude Code CX Codex Cursor +1 38,000installs flutter-setup-declarative-routing flutter Sets up Flutter routing with go_router, including URL-based screens, nested navigation, and deep links for web and mobile apps. Claude Code CX Codex Cursor +1 37,600installs flutter-implement-json-serialization flutter Teaches coding agents to build Dart models with fromJson and toJson methods using dart:convert. Useful for manual JSON mapping in simple Flutter data structures. Claude Code CX Codex Cursor +1 37,200installs flutter-add-widget-preview flutter Configures interactive Flutter widget previews with package:flutter/widget_previews.dart. Useful for testing UI components in isolation without launching the whole app. Claude Code CX Codex Cursor +1 36,600installs flutter-setup-localization flutter This skill automates initialization of multi-language support in Flutter projects. It adds dependencies, enables code generation, and creates a configuration file for .arb-based translations. Claude Code CX Codex Cursor +1 36,600installs flutter-use-http-package flutter This skill shows how to send GET, POST, PUT, and DELETE requests with Flutter's http package and handle JSON responses. Use it when an app needs to read from or write to a REST API. Claude Code CX Codex Cursor +1 36,000installs

Similar

laravel-specialist https://github.com/Jeffallan Configures the agent for Laravel 10+ and PHP 8.2+ development. It guides Eloquent modeling, Horizon queues, API resources, and Pest testing. Claude Code CX Codex Cursor +1 23,300installs tdd-rust rtk-ai Skill for RTK filter development using TDD. Write a test with real data, implement minimum code, verify token savings, lock the output format with insta snapshots. Claude Code CX Codex Cursor +1 1,400installs dotnet-backend-patterns Seth Hobson Skill for C# and .NET development: patterns for async code, dependency injection, Entity Framework Core, caching, and testing. Use when building backend APIs, MCP servers, or reviewing C# code. Claude Code CX Codex Cursor 19,076installs unlazy Leonxlnx This skill sets testable completion gates, breaks complex work into stages, and rechecks evidence before the agent reports completion. Claude Code CX Codex Cursor +1 9,400installs audit-xls official anthropics Audits Excel sheets for formula errors, hardcoded values, and logic breaks. It checks financial model integrity before sharing work with clients or review committees. Claude Code CX Codex Cursor +1 2,200installs improve-codebase-architecture Matt Pocock This skill scans a codebase for architectural friction, then builds a visual HTML report with refactoring candidates. Use it before a deeper architecture review. Claude Code 1,163,035installs design-taste-frontend Leonxlnx This skill directs the design of public pages and work screens, then checks the result in a browser through screenshots. Use it when an interface feels generic or unfinished. Claude Code CX Codex Cursor +1 673,100installs tdd Matt Pocock Guides the red-green TDD loop: ensures tests are written first, keep them at public interfaces, and avoid coupling to implementation details. Claude Code 1,141,062installs

Questions about flutter-add-widget-test

How do I install flutter-add-widget-test in Claude Code?

Run npx skills add flutter/agent-plugins --skill flutter-add-widget-test -a claude-code, then the skill is available in ~/.claude/skills/flutter-add-widget-test/SKILL.md.

What does flutter-add-widget-test do?

It shows how to write a component test with flutter_test: how to use WidgetTester, Finder, and Matcher; how to simulate user interactions; and how to verify widget state changes.

When should I use tester.pump() instead of tester.pumpAndSettle()?

Use pump() after simple actions like a button tap if there is no animation. Use pumpAndSettle() when you need to wait for an animation to finish or an async UI update to complete.

Source text

SKILL.md · BSD-3-Clause
---
name: flutter-add-widget-test
description: Implement a component-level test using `WidgetTester` to verify UI rendering and user interactions (tapping, scrolling, entering text). Use when validating that a specific widget displays correct data and responds to events as expected.
metadata:
  model: models/gemini-3.1-pro-preview
  last_modified: Tue, 21 Apr 2026 21:15:41 GMT
---
# Writing Flutter Widget Tests

## Contents
- [Setup & Configuration](#setup--configuration)
- [Core Components](#core-components)
- [Workflow: Implementing a Widget Test](#workflow-implementing-a-widget-test)
- [Interaction & State Management](#interaction--state-management)
- [Examples](#examples)

## Setup & Configuration

Ensure the testing environment is properly configured before authoring widget tests.

1. Add the `flutter_test` dependency to the `dev_dependencies` section of `pubspec.yaml`.
2. Place all test files in the `test/` directory at the root of the project.
3. Suffix all test file names with `_test.dart` (e.g., `widget_test.dart`).

## Core Components

Utilize the following `flutter_test` components to interact with and validate the widget tree:

*   **`WidgetTester`**: The primary interface for building and interacting with widgets in the test environment. Provided automatically by the `testWidgets()` function.
*   **`Finder`**: Locates widgets in the test environment (e.g., `find.text('Submit')`, `find.byType(TextField)`, `find.byKey(Key('submit_btn'))`).
*   **`Matcher`**: Verifies the presence or state of widgets located by a `Finder` (e.g., `findsOneWidget`, `findsNothing`, `findsNWidgets(2)`, `matchesGoldenFile`).

## Workflow: Implementing a Widget Test

Copy the following checklist to track progress when implementing a new widget test.

### Task Progress
- [ ] **Step 1: Define the test.** Use `testWidgets('description', (WidgetTester tester) async { ... })`.
- [ ] **Step 2: Build the widget.** Call `await tester.pumpWidget(MyWidget())` to render the UI. Wrap the widget in a `MaterialApp` or `Directionality` widget if it requires inherited directional or theme data.
- [ ] **Step 3: Locate elements.** Instantiate `Finder` objects for the target widgets.
- [ ] **Step 4: Verify initial state.** Use `expect(finder, matcher)` to validate the initial render.
- [ ] **Step 5: Simulate interactions.** Execute gestures or inputs (e.g., `await tester.tap(buttonFinder)`).
- [ ] **Step 6: Rebuild the tree.** Call `await tester.pump()` or `await tester.pumpAndSettle()` to process state changes.
- [ ] **Step 7: Verify updated state.** Use `expect()` to validate the UI after the interaction.
- [ ] **Step 8: Run and validate.** Execute `flutter test test/your_test_file_test.dart`.
- [ ] **Step 9: Feedback Loop.** Review test output -> identify failing matchers -> adjust widget logic or test assertions -> re-run until passing.

## Interaction & State Management

Apply the following conditional logic based on the type of interaction or state change being tested:

*   **If testing static rendering:** Call `await tester.pumpWidget()` once, then immediately run `expect()` assertions.
*   **If testing standard state changes (e.g., button taps):** 
    1. Call `await tester.tap(finder)`.
    2. Call `await tester.pump()` to trigger a single frame rebuild.
*   **If testing animations, transitions, or asynchronous UI updates:** 
    1. Trigger the action (e.g., `await tester.drag(finder, Offset(500, 0))`).
    2. Call `await tester.pumpAndSettle()` to repeatedly pump frames until no more frames are scheduled (animation completes).
*   **If testing text input:** Call `await tester.enterText(textFieldFinder, 'Input string')`.
*   **If testing items in a dynamic or long list:** Call `await tester.scrollUntilVisible(itemFinder, 500.0, scrollable: listFinder)` to ensure the target widget is rendered before interacting with it.

## Examples

### High-Fidelity Widget Test Implementation

**Target Widget (`lib/todo_list.dart`):**
```dart
import 'package:flutter/material.dart';

class TodoList extends StatefulWidget {
  const TodoList({super.key});

  @override
  State<TodoList> createState() => _TodoListState();
}

class _TodoListState extends State<TodoList> {
  final todos = <String>[];
  final controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Column(
          children: [
            TextField(controller: controller),
            Expanded(
              child: ListView.builder(
                itemCount: todos.length,
                itemBuilder: (context, index) {
                  final todo = todos[index];
                  return Dismissible(
                    key: Key('$todo$index'),
                    onDismissed: (_) => setState(() => todos.removeAt(index)),
                    child: ListTile(title: Text(todo)),
                  );
                },
              ),
            ),
          ],
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {
              todos.add(controller.text);
              controller.clear();
            });
          },
          child: const Icon(Icons.add),
        ),
      ),
    );
  }
}
```

**Test Implementation (`test/todo_list_test.dart`):**
```dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:my_app/todo_list.dart';

void main() {
  testWidgets('Add and remove a todo item', (WidgetTester tester) async {
    // 1. Build the widget
    await tester.pumpWidget(const TodoList());

    // 2. Verify initial state
    expect(find.byType(ListTile), findsNothing);

    // 3. Enter text into the TextField
    await tester.enterText(find.byType(TextField), 'Buy groceries');

    // 4. Tap the add button
    await tester.tap(find.byType(FloatingActionButton));

    // 5. Rebuild the widget to reflect the new state
    await tester.pump();

    // 6. Verify the item was added
    expect(find.text('Buy groceries'), findsOneWidget);

    // 7. Swipe the item to dismiss it
    await tester.drag(find.byType(Dismissible), const Offset(500, 0));

    // 8. Build the widget until the dismiss animation ends
    await tester.pumpAndSettle();

    // 9. Verify the item was removed
    expect(find.text('Buy groceries'), findsNothing);
  });
}
```

© flutter · BSD-3-Clause · flutter/agent-plugins

See also

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor