An introduction to integration testing
Unit tests and widget tests are handy for testing individual classes, functions, or widgets. However, they generally don’t test how individual pieces work together as a whole, or capture the performance of an application running on a real device. These tasks are performed with integration tests.
Integration tests are written using the integration_test package, provided by the SDK.
In this recipe, learn how to test a counter app. It demonstrates how to setup integration tests, how to verify specific text is displayed by the app, how to tap specific widgets, and how to run integration tests.
This recipe uses the following steps:
- Create an app to test.
- Add the
integration_test
dependency. - Create the test files.
- Write the integration test.
- Run the integration test.
1. Create an app to test
First, create an app for testing. In this example,
test the counter app produced by the flutter create
command. This app allows a user to tap on a button
to increase a counter.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Counter App',
home: MyHomePage(title: 'Counter App Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
// Provide a Key to this specific Text widget. This allows
// identifying the widget from inside the test suite,
// and reading the text.
key: const Key('counter'),
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
// Provide a Key to this button. This allows finding this
// specific button inside the test suite, and tapping it.
key: const Key('increment'),
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
integration_test
dependency
2. Add the Next, use the integration_test
and flutter_test
packages
to write integration tests. Add these dependencies to the dev_dependencies
section of the app’s pubspec.yaml
file, specifying the Flutter SDK as the
location of the package.
dev_dependencies:
integration_test:
sdk: flutter
flutter_test:
sdk: flutter
3. Create the test files
Create a new directory, integration_test
, with an empty app_test.dart
file:
counter_app/
lib/
main.dart
integration_test/
app_test.dart
4. Write the integration test
Now you can write tests. This involves three steps:
- Initialize
IntegrationTestWidgetsFlutterBinding
, a singleton service that executes tests on a physical device. - Interact and tests widgets using the
WidgetTester
class. - Test the important scenarios.
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:counter_app/main.dart' as app;
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('end-to-end test', () {
testWidgets('tap on the floating action button, verify counter',
(tester) async {
app.main();
await tester.pumpAndSettle();
// Verify the counter starts at 0.
expect(find.text('0'), findsOneWidget);
// Finds the floating action button to tap on.
final Finder fab = find.byTooltip('Increment');
// Emulate a tap on the floating action button.
await tester.tap(fab);
// Trigger a frame.
await tester.pumpAndSettle();
// Verify the counter increments by 1.
expect(find.text('1'), findsOneWidget);
});
});
}
5. Run the integration test
The process of running the integration tests varies depending on the platform you are testing against. You can test against a mobile platform or the web.
5a. Mobile
To test on a real iOS / Android device, first connect the device and run the following command from the root of the project:
flutter test integration_test/app_test.dart
Or, you can specify the directory to run all integration tests:
flutter test integration_test
This command runs the app and integration tests on the target device. For more information, see the Integration testing page.
5b. Web
To get started testing in a web browser, Download ChromeDriver.
Next, create a new directory named test_driver
containing a new file
named integration_test.dart
:
import 'package:integration_test/integration_test_driver.dart';
Future<void> main() => integrationDriver();
Launch chromedriver
as follows:
chromedriver --port=4444
From the root of the project, run the following command:
flutter drive \
--driver=test_driver/integration_test.dart \
--target=integration_test/app_test.dart \
-d chrome
For a headless testing experience, you can also run flutter drive
with web-server
as the target device identifier as follows:
flutter drive \
--driver=test_driver/integration_test.dart \
--target=integration_test/app_test.dart \
-d web-server