Flutter provides various classes to test user interface of an app. Flutter Driver class is one from the pack that helps to drive the application in another process (read: instrumented app) and exposes different helpful methods to test user interaction and interface of the app.

In this article, I am going to discuss how do we make use of Flutter Driver to test basic user interaction with the app.

What is Flutter Driver ?

In simple terms, if you have read or used various testing frameworks for web or mobile platforms such as Selenium WebDriver , Protractor for AngularJS and Google Espresso for Android, on similar lines, Flutter Driver is for Flutter. You can read more about Flutter Driver here.

Demo app

we’ll use a simple input textfield followed by a button at center of the screen and will validate functioning of these two widgets as a flow using Flutter driver methods.

Simple UI under test

Flutter Driver setup

Before we could start using Flutter Driver class, we need to make 2 new test files under a predefined folder named test_driver . First file will contain the method that enables Flutter driver extension followed by calling the function which contains the widgets we need to test. So, the first file, let’s name it as app.dart will look like this:

void main() {

// This line enables the extension

enableFlutterDriverExtension();



// Call the `main()` function of your app or call `runApp` with any widget you

// are interested in testing.

app.main();

}

The second file will contain the actual test scripts that we are going to write by using driver methods. Let’s name it app_test.dart which will contain methods to connect to Flutter driver and closing the connection once all tests are completed, followed by test scripts.

void main() {

group('Flutter Driver demo', () {

FlutterDriver driver;



setUpAll(() async {

driver = await FlutterDriver.connect();

});



tearDownAll(() async {

if (driver != null) {

await driver.close();

}

});

You can read about the driver setup in more details here.

Note: the above link shows how to add the flutter driver dependency in pubspec.yaml, so I am going to skip that part here.

Now that we have added the required files to connect to Flutter driver, we first need to check the status of the driver extension before writing and executing our test scripts. Enter checkHealth()

checkHealth(): This method verifies the status of Flutter Driver extension we use for our tests. It would be a good practice to execute this method first before we start running tests, because we don’t want our tests to fail due to unavailability or bad status of Flutter Driver.

In app_test.dart , let’s write our first test, as below:

test('check flutter driver health', () async {

Health health = await driver.checkHealth();

print(health.status);

});

Very simple method to implement. To see the status, we’ll need to run this test from command line. From terminal, go to the root path of your project and use this command to run our test:

$ flutter drive — target=test_driver/app.dart

00:01 +0: Flutter Driver demo check flutter driver health HealthStatus.ok 00:01 +1: Flutter Driver demo (tearDownAll) 00:01 +1: All tests passed! Stopping application instance.

Great ! we are now good to write actual test scripts to validate the UI.

Now, we will write a script to enter a text in input field, validate that the entered text is displayed in the field, update the input field with new text and then validate that the first text entered is not present, followed by tapping on the button and then scrolling to the widget present at the bottom of the screen. For this test, we’ll make use of following methods:

tap()

enterText()

waitFor()

waitForAbsent()

scrollIntoView()

Test script for above scenario will look like this:

test('Flutter drive methods demo', () async {



await driver.tap(find.byValueKey('inputKeyString'));

await driver.enterText('Hello !');

await driver.waitFor(find.text('Hello !'));

await driver.enterText('World');

await driver.waitForAbsent(find.text('Hello !'));

print('World'); await driver.waitFor(find.byValueKey('button'));

await driver.tap(find.byValueKey('button'));

print('Button clicked'); await driver.waitFor(find.byValueKey('text'));

await driver.scrollIntoView(find.byValueKey('text'));

await driver.waitFor(find.text('Scroll till here'));

print('I found you buddy !'); });

Let’s go through each line one by one.

await driver.tap(find.byValueKey(‘inputKeyString’));

When the instrumented app is launched, the input textfield and button widgets are rendered and in order to insert a text in input field, we first need to tell driver to find the input field and then tap on it to make the input field enabled.

inputKeyString is a key we need to declare in our main.dart file in order to uniquely identify each widget.

await driver.enterText('Hello !');

enterText as its name suggests, helps to enter the text-in-test to input in the given textfield. Since the textfield is now enabled, we instruct driver to enter the text Hello ! in it.

await driver.waitFor(find.text('Hello !'));

waitFor method tells the driver to wait till the given text is found.

Note: Ideally getText() should work with all widgets like TextField , RaisedButton and so on, but it seems it currently supports only Text widget. Source: https://github.com/flutter/flutter/issues/16013

await driver.enterText('World');

Above line replaces the first text Hello ! with World

await driver.waitForAbsent(find.text('Hello !'));

waitForAbsent when used, tells driver to wait until the target specified in finder is no longer available.

await driver.waitFor(find.byValueKey('button'));

await driver.tap(find.byValueKey('button'));

Before we could tap on the button, we first need to find it using find.byValueKey and then tap it.

await driver.waitFor(find.byValueKey('text'));

await driver.scrollIntoView(find.byValueKey('text'));

await driver.waitFor(find.text('Scroll till here'));

Now that we have validated button tap, we’ll need to find the text present at the bottom of the screen. For this, we’ll use scrollIntoView method, but before that we need to instruct driver to find the text widget then scroll into it using key and then validate the text displayed.

Let’s run the script and see the output: