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);
});
}
1---2name: add-widget-tests3description: Writing Flutter Widget Tests4---56# Writing Flutter Widget Tests78This 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`.910## Core Requirements1112Each widget test suite must include:13141. **Imports**:15 - `package:flutter/material.dart`16 - `package:flutter_test/flutter_test.dart`17 - `package:boutique/cart.dart`18 - The screen being tested (e.g., `package:boutique/screens/cart_screen.dart`).19202. **Clean State Setup**:21 - Every test must run in a clean environment. Call `Cart.instance.clear()` inside a `setUp` block to reset the cart's value listenables.22 ```dart23 setUp(() => Cart.instance.clear());24 ```25263. **MaterialApp Harness**:27 - Define a local helper function `harness()` that returns the target screen wrapped in a `MaterialApp`.28 ```dart29 Widget harness() => const MaterialApp(home: TargetScreen());30 ```31324. **"renders" Test Case**:33 - At least one `testWidgets` block that asserts the initial UI components render correctly.34 - Use `tester.pumpWidget(harness())` to load the widget.35 - Verify visible static texts, icons, or headers.36 ```dart37 testWidgets('renders ... description', (tester) async {38 await tester.pumpWidget(harness());39 expect(find.text('Expected Screen Title'), findsOneWidget);40 });41 ```42435. **"behaves" Test Case**:44 - At least one `testWidgets` block that simulates user interaction or reactivity.45 - Verify initial state, perform an interaction (e.g., `tester.tap()`), call `tester.pump()`, and verify the updated UI state or underlying model state.46 ```dart47 testWidgets('interaction behaves correctly', (tester) async {48 await tester.pumpWidget(harness());49 // Assert initial state50 // Act (tap, input, etc.)51 // Pump to trigger rebuilds52 // Assert ending state53 });54 ```5556## Example Implementation Reference5758Compare your implementation to the existing `test/catalog_screen_test.dart`:59```dart60import 'package:flutter/material.dart';61import 'package:flutter_test/flutter_test.dart';62import 'package:boutique/cart.dart';63import 'package:boutique/screens/catalog_screen.dart';6465void main() {66 setUp(() => Cart.instance.clear());6768 Widget harness() => const MaterialApp(home: CatalogScreen());6970 testWidgets('renders the storefront title and a product', (tester) async {71 await tester.pumpWidget(harness());7273 expect(find.text('Lavender Boutique'), findsOneWidget);74 expect(find.text('Lavender Sleep Mist'), findsOneWidget);75 });7677 testWidgets('adding a product puts it in the cart', (tester) async {78 await tester.pumpWidget(harness());7980 expect(Cart.instance.items.value, isEmpty);81 await tester.tap(find.widgetWithText(FilledButton, 'Add').first);82 await tester.pump();8384 expect(Cart.instance.items.value.length, 1);85 });86}87```