IN: +91-858-606-7842

Integration Testing With Flutter

Many reasons support the importance of testing software. It helps to identify any errors, bugs, or defects and rectify them before delivering the software to the client. By doing so, it makes the software more efficient, reliable, and easy to use.

There are many levels of testing that aim to make the software testing process systematic. They help identify all possible test cases and check the behavior and performance of the software at different levels.

Different Levels of Testing

Broadly, there are four recognized levels of software testing. They are frequently grouped depending on where they are added during the development phase or their specificity level.

  1. Unit/Component Testing
  2. Integration testing
  3. System testing
  4. Acceptance testing

1 – Unit/Component Testing

It is the most basic type of testing. Unit testing looks to verify each software component by isolating it and performing tests to ascertain whether each element works according to the desired functionality. Although a unit test can be performed at any time, it is usually executed by a developer during the early stages of software development. It helps detect errors and rectify them early to minimize risks and save on the time and money needed to undo the problems once the software is nearly complete.

2 – System Testing

Under system testing, all software components are tested together in a simulated environment close to the actual operating environment. It helps ensure that the software complies with the specified requirements and runs smoothly once deployed in the real working environment. A specialized testing team generally performs system testing.

3 – Acceptance Testing

Acceptance testing evaluates whether the software meets the end-user requirements and is ready to be deployed. The testing team uses various methods such as pre-written scenarios and test cases to assess and utilize the results obtained to judge if they can give the software the green light or not. The test scope could range from a simple task such as finding spelling or grammatical errors to more complex ones such as discovering bugs that can cause significant errors.

4 – Integration Testing

And now we come to the lead character of this post, integration testing.

The objective of integration testing is to test individual components and assess how well they perform together. Conjoining the different components helps understand the multiple modules that operate as a single unit and helps identify any faults that may exist, such as mistaken cache integration, a broken database schema, and others.

Integration testing follows two approaches, the bottom-up approach, and the top-down approach. The bottom-up approach involves studying simpler modules first before moving on to the more complex modules. The top-down approach examines more complex modules first before moving down to inspect the simpler ones. The testing team performs integration testing after the unit test but before the system test.

What is a Flutter Driver?

A flutter driver is a framework used to test flutter apps. It provides the tools needed to create and drive instrumented apps from a test suite. Flutter driver is used to testing various UI elements and helps developers write end-to-end integration tests. It significantly reduces the time and effort needed to test apps traditionally and is easy to set up and use.

Flutter Driver Package and Integration Tests

The flutter driver package runs integration tests written in Dart on a particular device and reports the results back to the host. Tests written using the flutter driver package run from the host and drive the app running on a virtual or actual device. Developers use the flutter drive command to run tests written using the flutter driver package.

Let us now understand how to set up and run integration tests using the flutter driver.

Step 1 – Create an Application to Test

The first step is to create an app to test. This post will walk you through how to test the counter app developed using the flutter create command. The counter app allows a user to increase a counter by merely tapping a button. Also, provide a Value Key to the Text and FloatingActionButton widgets. It makes identifying and interacting with these widgets inside the test suite easy.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Counter App',
      home: MyHomePage(title: 'Counter App Home Page'),

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  _MyHomePageState createState() => _MyHomePageState();

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      body: Center(
        child: Column(
          children: <Widget>[
              'You have pushed the button this many times:',
              // Provide a Key to this specific Text widget. This allows
              // identifying the widget from inside the test suite,
              // and reading the text.
              key: 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: Key('increment'),
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),

Step 2 – Add the Flutter Driver Dependency

To use the flutter drive package to write integration tests, add the flutter driver dependency to the dev_dependencies section of your pubspec.yaml file. Also, ensure that you add the test dependency to use the actual test functions and assertions.

    sdk: flutter
  test: any

Step 3 – Create Your Test Files

Unlike unit and widget tests, integration tests work as a pair and do not run in the same process as the app that is being tested. First, you need to install an instrumented application to an actual or emulator device and then drive the application from a different test suite. Therefore, you need to create two separate files that reside within the same directory. By default, the directory is named test_driver.

  1. As highlighted earlier, the first file will contain an instrumented version of the application. It allows you to drive the app and record performance profiles. You can give the file any name that makes sense. In this post, let’s name this file as test_driver/app.dart.
  2. The second file will contain the test suite. The test suite drives the app and checks to ensure it is working as expected. It also records performance profiles that we discussed in the previous point. This file’s name should correspond to the name of the file containing the instrumented app, with _test added at the end. In our case, this file’s name would be test_driver/app_test.dart.

The directory structure will look like this:


Step 4 – Instrument the Application

The next step is to instrument the application. It involves two simple steps:

  1. Enable the flutter driver extensions.
  2. Run the application.

You will need to add the following code to the file named test_driver/app.dart.

import 'package:flutter_driver/driver_extension.dart';
import 'package:counter_app/main.dart' as app;

void main() {
  // This line enables the extension.

  // Call the `main()` function of the app, or call `runApp` with
  // any widget you are interested in testing.

Step 5 – Write the Integration Tests

After you are done instrumenting the application, you can start writing integration tests for it. The process involves four steps:

  1. Creating SerializableFinders to locate specific widgets.
  2. Connecting to the app before the tests run in the setUpAll() function.
  3. Testing the critical scenarios.
  4. Disconnecting from the application using the teardownAll() function after you finish testing.
// Imports the Flutter Driver API.
import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';

void main() {
  group('Counter App', () {
    // First, define the Finders and use them to locate widgets from the
    // test suite. Note: the Strings provided to the `byValueKey` method must
    // be the same as the Strings we used for the Keys in step 1.
    final counterTextFinder = find.byValueKey('counter');
    final buttonFinder = find.byValueKey('increment');

    FlutterDriver driver;

    // Connect to the Flutter driver before running any tests.
    setUpAll(() async {
      driver = await FlutterDriver.connect();

    // Close the connection to the driver after the tests have completed.
    tearDownAll(() async {
      if (driver != null) {

    test('starts at 0', () async {
      // Use the `driver.getText` method to verify the counter starts at 0.
      expect(await driver.getText(counterTextFinder), "0");

    test('increments the counter', () async {
      // First, tap the button.
      await driver.tap(buttonFinder);

      // Then, verify the counter text is incremented by 1.
      expect(await driver.getText(counterTextFinder), "1");

The flutter_driver package waits until there are no pending frames. If that be the case, wrap the driver actions in the runUnsynchronized mode using the following code:

test('increments the counter during animation', () async {
  await driver.runUnsynchronized(() async {
    // First, tap the button.
    await driver.tap(buttonFinder);

    // Then, verify the counter text is incremented by 1.
    expect(await driver.getText(counterTextFinder), "1");

Step 6 – Run the Integration Tests

Now that you have instrumented the app and the test suite and have written the integration tests, it is time to execute or run the tests. The process of running your integration tests depends on the platform you are testing against, for example, a mobile or a web platform.

To Run the Integration Tests on a Mobile Platform

To run the tests on iOS or Android platforms, launch an iOS simulator or an Android emulator. You can also connect your PC to an actual iOS or Android device. After this is done, run the following command from the project’s root.

flutter drive --target=test_driver/app.dart

The command above performs the following three functions:

  • It builds the –target application and installs it on the emulator or the device.
  • It launches the application.
  • It runs the app_test.dart test suite located in the test_driver/folder.

To Run the Integration Tests on a Web Platform

To run the tests for web platforms, you need first to decide which browser you want to test against and then download the corresponding web driver:

  • For Chrome: Download ChromeDriver
  • For Firefox: Download GeckoDriver
  • For Safari: You can only test Safari on a Mac machine. The Safari driver is pre-installed on Mac computers.
  • For Edge: Download EdgeDriver

Next, launch the web driver. For example, if you want to launch Chrome, use the following command:

./chromedriver --port=4444

After you launch the web browser, run the following command from the root of the project:

flutter drive --target=test_driver/app.dart --browser-name=[browser name] --release

Lastly, you can use the –browser-dimension argument to simulate different screen dimensions, for example:

flutter drive --target=test_driver/app.dart --browser-name=chrome --browser-dimension 300,550 --release


Running integration tests early and frequently is worth the time and effort. If you constantly stay alert and follow a systematic approach, integration tests can help detect faults and errors early on. It helps save the time and effort needed to fix issues later when the project is nearing completion. Integration tests are essential as even a single minor bug in a hidden component can result in an error that can negatively affect the whole project.

Now, it’s your turn to add your view for this article.

I’d like to hear what you have to say. If this article has any error share with us by leaving a comment below.