Integration testing checks if different parts of your app work well together. It helps find problems that unit tests might miss.
Integration testing in Flutter
import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('test description', (WidgetTester tester) async { // Build app await tester.pumpWidget(MyApp()); // Interact with widgets await tester.tap(find.text('Login')); await tester.pumpAndSettle(); // Verify results expect(find.text('Welcome'), findsOneWidget); }); }
Use IntegrationTestWidgetsFlutterBinding.ensureInitialized() to set up integration testing.
Use testWidgets to write tests that interact with the UI.
IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('tap button shows text', (tester) async { await tester.pumpWidget(MyApp()); await tester.tap(find.byType(ElevatedButton)); await tester.pumpAndSettle(); expect(find.text('Button tapped'), findsOneWidget); });
IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('navigate to next page', (tester) async { await tester.pumpWidget(MyApp()); await tester.tap(find.text('Next')); await tester.pumpAndSettle(); expect(find.text('Second Page'), findsOneWidget); });
This integration test runs the app with a login button. When the button is tapped, it shows a welcome message. The test checks this behavior.
import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('login button shows welcome message', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp( home: Scaffold( body: LoginScreen(), ), )); expect(find.text('Welcome'), findsNothing); await tester.tap(find.text('Login')); await tester.pumpAndSettle(); expect(find.text('Welcome'), findsOneWidget); }); } class LoginScreen extends StatefulWidget { @override State<LoginScreen> createState() => _LoginScreenState(); } class _LoginScreenState extends State<LoginScreen> { bool loggedIn = false; @override Widget build(BuildContext context) { return Center( child: loggedIn ? Text('Welcome') : ElevatedButton( onPressed: () { setState(() { loggedIn = true; }); }, child: Text('Login'), ), ); } }
Integration tests run slower than unit tests because they start the app and interact with the UI.
Use pumpAndSettle() to wait for animations and UI updates to finish.
Run integration tests on real devices or emulators for best results.
Integration testing checks if app parts work together correctly.
Use IntegrationTestWidgetsFlutterBinding.ensureInitialized() to set up.
Write tests that tap, type, and check UI changes.
Practice
Solution
Step 1: Understand integration testing goal
Integration testing focuses on how different parts of the app interact and work together.Step 2: Compare with other test types
Unit tests check individual functions, performance tests check speed, and UI design tests check visuals.Final Answer:
To check if different parts of the app work together correctly -> Option DQuick Check:
Integration testing = check parts working together [OK]
- Confusing integration testing with unit testing
- Thinking it tests only UI colors
- Mixing it up with performance testing
Solution
Step 1: Identify the correct binding for integration tests
The official Flutter integration test package uses IntegrationTestWidgetsFlutterBinding.ensureInitialized() to set up.Step 2: Check other options for correctness
WidgetsFlutterBinding is for widget tests, not integration tests. Others are incorrect or do not exist.Final Answer:
IntegrationTestWidgetsFlutterBinding.ensureInitialized(); -> Option AQuick Check:
Use IntegrationTestWidgetsFlutterBinding for integration tests [OK]
- Using WidgetsFlutterBinding instead of IntegrationTestWidgetsFlutterBinding
- Misspelling the method name
- Trying to call a non-existent initialize() method
final button = find.text('Tap me');
await tester.tap(button);
await tester.pumpAndSettle();
expect(find.text('Tapped!'), findsOneWidget);Solution
Step 1: Analyze the tap action
The test finds a button with text 'Tap me' and taps it.Step 2: Check the expected result
After tapping and waiting for animations, it expects to find text 'Tapped!' on screen.Final Answer:
The button labeled 'Tap me' is tapped and text changes to 'Tapped!' -> Option CQuick Check:
Tap 'Tap me' button, expect 'Tapped!' text [OK]
- Confusing which text is tapped and which is expected
- Ignoring await pumpAndSettle() for UI update
- Assuming no tap happens
void main() {
testWidgets('tap test', (tester) async {
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
final button = find.text('Click');
await tester.tap(button);
expect(find.text('Clicked'), findsOneWidget);
});
}Solution
Step 1: Check binding initialization placement
IntegrationTestWidgetsFlutterBinding.ensureInitialized() should be called once before all tests, not inside testWidgets.Step 2: Verify other code parts
find.text syntax is correct, await is used before tap, and expect is correctly after tap.Final Answer:
Binding initialization should be outside testWidgets, in main() before tests -> Option AQuick Check:
Initialize binding once before tests [OK]
- Calling ensureInitialized inside each testWidgets
- Forgetting await before tap
- Misordering expect before tap
Solution
Step 1: Enter text into the TextField
Use tester.enterText with find.byType(TextField) to type 'hello'.Step 2: Tap the 'Send' button and wait for UI update
Tap the button found by text 'Send' and call pumpAndSettle() to wait for animations.Final Answer:
await tester.enterText(find.byType(TextField), 'hello'); await tester.tap(find.text('Send')); await tester.pumpAndSettle(); -> Option BQuick Check:
Type first, then tap button, then wait [OK]
- Tapping button before typing text
- Using wrong finder for TextField or button
- Not waiting with pumpAndSettle after tap
Ready to prove it?
Pass the test and this pattern moves unknown
