| name | add-widget-tests |
| description | Writes a Flutter widget test for a given screen following the convention in test/catalog_screen_test.dart: a MaterialApp harness, Cart.instance.clear() in setUp, and at least one "renders" and one "behaves" testWidgets case asserting on visible content. |
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:
-
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).
-
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.
setUp(() => Cart.instance.clear());
-
MaterialApp Harness:
- Define a local helper function
harness() that returns the target screen wrapped in a MaterialApp.
Widget harness() => const MaterialApp(home: TargetScreen());
-
"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.
testWidgets('renders ... description', (tester) async {
await tester.pumpWidget(harness());
expect(find.text('Expected Screen Title'), findsOneWidget);
});
-
"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.
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:
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);
});
}