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.dartpackage:flutter_test/flutter_test.dartpackage: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 asetUpblock to reset the cart's value listenables.
setUp(() => Cart.instance.clear());- Every test must run in a clean environment. Call
MaterialApp Harness:
- Define a local helper function
harness()that returns the target screen wrapped in aMaterialApp.
Widget harness() => const MaterialApp(home: TargetScreen());- Define a local helper function
"renders" Test Case:
- At least one
testWidgetsblock 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); });- At least one
"behaves" Test Case:
- At least one
testWidgetsblock that simulates user interaction or reactivity. - Verify initial state, perform an interaction (e.g.,
tester.tap()), calltester.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 });- At least one
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);
});
}