Flutter Integration Testing Tutorial with A Working Example
šŸ¦

Flutter Integration Testing Tutorial with A Working Example

Tags
Last edited time
Last updated May 10, 2023
Format and Platform
In this tutorial, we'll cover the process of setting up and running integration tests in Flutter using the integration_test package. We'll use testing code for The Playlist app (available on Google Play). By the end of this tutorial, you'll have a solid understanding of how to perform end-to-end testing for your Flutter app.
notion image

Setting up the Project for Integration Testing

First, you'll need to add theĀ integration_testĀ package to yourĀ pubspec.yamlĀ file as a dev dependency:
dev_dependencies: integration_test: sdk: flutter flutter_test: sdk: flutter
After adding the package, runĀ flutter pub getĀ to install it.
Ā 
Step 1: Setup test environment
Create a new file calledĀ integration_test/app_test.dart. In this file, import the necessary libraries:
import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:your_app_package/your_app.dart'; // Replace with the import to your main app file
Ā 
Step 2: Write helper functions
Before diving into the main test, let's create some helper functions that will be used in the test, we use helper functions for reusability purpose:
  • createPlaylist: Creates a new playlist
  • openPlaylistsPage: Opens the playlists page
  • editPlaylistTitle: Edits the playlist title
  • editPlaylistDate: Edits the playlist date
  • deletePlaylist: Deletes the playlist
We will expand on these later.
Ā 
Step 3: Write the main test
Now, let's write the main test function that will use the helper functions to test the app's functionality. The provided code in the question can be used as a starting point:
void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('Test Playlist', () { testWidgets('create, edit, delete playlist', (tester) async { // Build our app and trigger a frame. const newPlaylistTitle = 'Test Playlist'; const editedPlaylistTitle = 'Edited Test Playlist'; const newPlaylistDate = '28'; app.main(); await tester.pumpAndSettle(const Duration(seconds: 1)); await createPlaylist(tester, newPlaylistTitle); expect(find.text(newPlaylistTitle), findsWidgets); await openPlaylistsPage(tester); await editPlaylistTitle(tester, newPlaylistTitle, editedPlaylistTitle); expect(find.text(editedPlaylistTitle), findsWidgets); await editPlaylistDate(tester, newPlaylistDate); await openPlaylistsPage(tester); expect(find.textContaining(newPlaylistDate), findsWidgets); await openPlaylistsPage(tester); await deletePlaylist(tester, editedPlaylistTitle); expect(find.text(editedPlaylistTitle), findsNothing); }); }); }
Ā 

Helper Functions

Let's take a look at helper functions that can perform actions such as creating, editing, and deleting playlists. Here's a breakdown of each function:

createPlaylist

This function first taps the "Add Playlist" button, then enters the givenĀ titleĀ into theĀ TextFormFieldĀ and taps the "Create" button. It uses theĀ pumpAndSettleĀ method to ensure the UI has time to update between interactions.
createPlaylist(WidgetTester tester, String title) async { await tester.pumpAndSettle(const Duration(milliseconds: 200)); await tester .tap(find.byKey(const Key('addPlaylistButton'), skipOffstage: false)); await tester.pumpAndSettle(const Duration(milliseconds: 200)); // Fill in the new playlist form await tester.enterText(find.byType(TextFormField).first, title); await tester.tap(find.text('Create')); await tester.pumpAndSettle(const Duration(milliseconds: 200)); }
Ā 

editPlaylistTitle

This function first taps on the playlist with the givenĀ title, then taps the edit icon in the app bar. It updates the playlist title with the providedĀ newTitleĀ and taps the "Update" button.
editPlaylistTitle(WidgetTester tester, String title, String newTitle) async { await tester.tap(find.text(title).first); await tester.pumpAndSettle(const Duration(milliseconds: 200)); // tap on edit icon in the topbar await tester.tap(find.byIcon(Icons.edit).first); await tester.pumpAndSettle(const Duration(milliseconds: 200)); // change the title of the playlist to "Edited Test Playlist" await tester.enterText(find.byType(TextFormField).first, newTitle); await tester.tap(find.text('Update')); await tester.pumpAndSettle(const Duration(milliseconds: 200)); }
Ā 

editPlaylistDate

This function taps the edit icon in the app bar, then taps the lastĀ TextFieldĀ to change the date of the playlist. It selects theĀ newDateĀ and taps the "OK" button. Finally, it taps the "Update" button.
editPlaylistDate(WidgetTester tester, String newDate) async { // tap on edit icon in the topbar await tester.pumpAndSettle(const Duration(milliseconds: 200)); await tester.tap(find.byIcon(Icons.edit).first); await tester.pumpAndSettle(const Duration(milliseconds: 200)); // change the date of the playlist to "Edited Test Playlist" await tester.tap(find.byType(TextField).last); await tester.pumpAndSettle(const Duration(milliseconds: 200)); await tester.tap(find.text(newDate).first); await tester.pumpAndSettle(const Duration(milliseconds: 200)); await tester.tap(find.text('OK')); await tester.pumpAndSettle(const Duration(milliseconds: 200)); await tester.tap(find.text('Update')); await tester.pumpAndSettle(const Duration(milliseconds: 200)); }
Ā 

deletePlaylist

This function first taps on the playlist with the givenĀ playlistTitle, then taps the delete icon in the app bar. It taps the "OK" button in the confirmation dialog to delete the playlist.
deletePlaylist(WidgetTester tester, String playlistTitle) async { await tester.pumpAndSettle(const Duration(milliseconds: 200)); await tester.tap(find.text(playlistTitle).first); await tester.pumpAndSettle(const Duration(milliseconds: 200)); // tap on delete icon in the topbar await tester.tap(find.byIcon(Icons.delete).first); await tester.pumpAndSettle(const Duration(milliseconds: 200)); // tap on delete button in the dialog await tester.tap(find.text('OK')); await tester.pumpAndSettle(const Duration(milliseconds: 200)); }
Ā 

openPlaylistsPage

This function navigates to the "Playlists" page by tapping on the "Playlists" text.
openPlaylistsPage(WidgetTester tester) async { await tester.pumpAndSettle(const Duration(milliseconds: 200)); await tester.tap(find.text("Playlists")); await tester.pumpAndSettle(const Duration(milliseconds: 200)); }
Ā 

Running the Integration Test

The test function is wrapped inside aĀ groupĀ called "Test Playlist". It tests the entire process of creating, editing, and deleting a playlist.
To run the test on a real iOS/Android device or emulator, use the following command in your terminal:
flutter test integration_test/app_test.dart
Alternatively, you can specify the directory to run all integration tests:
flutter test integration_test
This command will run the app and integration tests on the target device.
You can also run the test by opening the Testing tab and click on ā€œRun testā€ or ā€œDebug testā€.
notion image

Conclusion

This tutorial covers how to set up and run integration tests in Flutter using the integration_test package. Real working testing code from The Playlist app is used as a base, and each of the helper functions, as well as the main test function, are explained. By following these steps, you should now have a solid understanding of how to perform end-to-end testing on a Flutter app using integration tests.
Sources:
Ā