# Add Widget Tests

> Writing Flutter Widget Tests

- Skill: `evanca/add-widget-tests` (Agent Skill)
- Install (CLI): `npx skillmds@latest add evanca/add-widget-tests`
- Raw SKILL.md: https://api.skillmd.com/api/skills/evanca/add-widget-tests/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: evanca (https://skillmd.com/u/evanca)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/evanca/add-widget-tests

---


# Writing Flutter Widget Tests

This skill guides you through creating premium Flutter widget tests for screens in this project. All new widget tests must adhere strictly to the established conventions found in `test/catalog_screen_test.dart`.

## Core Requirements

Each widget test suite must include:

1. **Imports**:
   - `package:flutter/material.dart`
   - `package:flutter_test/flutter_test.dart`
   - `package:boutique/cart.dart`
   - The screen being tested (e.g., `package:boutique/screens/cart_screen.dart`).

2. **Clean State Setup**:
   - Every test must run in a clean environment. Call `Cart.instance.clear()` inside a `setUp` block to reset the cart's value listenables.
   ```dart
   setUp(() => Cart.instance.clear());
   ```

3. **MaterialApp Harness**:
   - Define a local helper function `harness()` that returns the target screen wrapped in a `MaterialApp`.
   ```dart
   Widget harness() => const MaterialApp(home: TargetScreen());
   ```

4. **"renders" Test Case**:
   - At least one `testWidgets` block that asserts the initial UI components render correctly.
   - Use `tester.pumpWidget(harness())` to load the widget.
   - Verify visible static texts, icons, or headers.
   ```dart
   testWidgets('renders ... description', (tester) async {
     await tester.pumpWidget(harness());
     expect(find.text('Expected Screen Title'), findsOneWidget);
   });
   ```

5. **"behaves" Test Case**:
   - At least one `testWidgets` block that simulates user interaction or reactivity.
   - Verify initial state, perform an interaction (e.g., `tester.tap()`), call `tester.pump()`, and verify the updated UI state or underlying model state.
   ```dart
   testWidgets('interaction behaves correctly', (tester) async {
     await tester.pumpWidget(harness());
     // Assert initial state
     // Act (tap, input, etc.)
     // Pump to trigger rebuilds
     // Assert ending state
   });
   ```

## Example Implementation Reference

Compare your implementation to the existing `test/catalog_screen_test.dart`:
```dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:boutique/cart.dart';
import 'package:boutique/screens/catalog_screen.dart';

void main() {
  setUp(() => Cart.instance.clear());

  Widget harness() => const MaterialApp(home: CatalogScreen());

  testWidgets('renders the storefront title and a product', (tester) async {
    await tester.pumpWidget(harness());

    expect(find.text('Lavender Boutique'), findsOneWidget);
    expect(find.text('Lavender Sleep Mist'), findsOneWidget);
  });

  testWidgets('adding a product puts it in the cart', (tester) async {
    await tester.pumpWidget(harness());

    expect(Cart.instance.items.value, isEmpty);
    await tester.tap(find.widgetWithText(FilledButton, 'Add').first);
    await tester.pump();

    expect(Cart.instance.items.value.length, 1);
  });
}
```

