In a fast-paced development environment, building high-quality mobile apps that provide an excellent user experience is key. This high quality can be ensured by thorough testing of these applications. Availability across numerous devices and platforms can be incredibly time-consuming. Fortunately, there are effective tools available to automate mobile app testing.
One increasingly popular framework for building mobile apps is Flutter. It allows you to create cross-platform mobile applications, which leads to rapid development. However, thorough testing of Flutter applications is still required as the impact of problems can be huge on the user base. Since manual testing can be time-consuming and error-prone, the best approach is to use the Appium automation framework.
In this article, we’ll go through an overview of Flutter and see how Flutter apps can be automated using Appium.
Overview of Flutter and Appium
Flutter is an open source framework developed by Google for building beautiful, high-performance mobile apps for iOS and Android using a single Dart code base. It comes with responsive views, powerful widgets and native performance. It also provides the advantage of a fast development cycle.
Appium is an open source automation testing framework for mobile applications. Enables automation in native, hybrid, and mobile web apps for iOS, Android, and Windows. Appium uses the WebDriver protocol to interact with applications.
Appium lets you write tests against Flutter apps using any WebDriver-compatible language, such as Java, Python, C#, Ruby, JavaScript, or PHP. We will use Java in this article for demonstrations.
Setting up Flutter
To get started with the Flutter framework, you need to have Appium installed and set up on your system. You can easily install Flutter by following the steps in the Flutter official documentation.
You can check the status of Flutter settings using the below command in terminal-
flutter doctor
If everything is installed, you will see the results as in the following screenshot, if not, you can fix the errors manually as it will be mentioned in the report.
Before you start building or opening a Flutter app in Android Studio, make sure that the Flutter and Dart plugins are installed in your Android Studio.
Running Flutter on Android Emulator
Once you’re done setting up Flutter, the next step would be to clone or import the Flutter app you want to automate. You can use your own app or refer to any of the example apps available to practice Flutter. For this article we will use a simple calculator application.
- Open Android Studio and open the app folder of your Flutter app.
- Next, we’ll open the pubspec.yml file and update it
dev_dependencies
as below:
dev_dependencies:
test: any
flutter_driver:
sdk: flutter
flutter_test:
sdk: flutter
The screenshot below shows the pubspec.yml file and the dependencies added.
3. After adding the dependencies, we will need to import them, which can be done using the below command in the terminal:
flutter pub get
4. Now we will update the main.dart file to import flutter_driver_extension
. We will write an import statement – import ‘package:flutter_driver/driver_extension.dart’
; and add method- enableFlutterDriverExtension()
in the main method. This should be written before runApp()
method. The code would look like this:
import 'package:flutter/material.dart';
import 'package:flutter_calculator/bindings/my_bindings.dart';
import 'package:flutter_calculator/screen/main_screen.dart';
import 'package:get/get.dart';
import 'package:flutter_driver/driver_extension.dart';
void main()
enableFlutterDriverExtension();
runApp(const MyApp());
class MyApp extends StatelessWidget
const MyApp(Key? key) : super(key: key);
@override
Widget build(BuildContext context)
return GetMaterialApp(
debugShowCheckedModeBanner: false,
initialBinding: MyBindings(),
title: "Flutter Calculator",
home: MainScreen(),
);
5. Once the above changes are done, we will run the Flutter app on the Android emulator. We will select the device we want to use to run our application.
6. Once the emulator is connected, click on the Run button
7. You will notice that the Flutter app opens in the emulator as shown in the screenshot.
Now that we know how to run a Flutter application on our system, in the next section we will learn about Appium Flutter Driver for automating Flutter applications.
Using the Appium Flutter driver to automate a Flutter application
Appium comes with a powerful extension called Appium Flutter Driver, which simplifies Flutter app automation using Appium. It acts as a bridge between test scripts and Flutter Driver.
-
The Appium Flutter Driver handles all the complex configurations of sending commands to the Flutter Driver, such as
- Automatically launch the Flutter Driver extension.
- Management of connection channels.
- Sending instructions for tests performed in isolation.
-
It is also cross-platform by allowing you to write test code once and deploy it on iOS and Android platforms.
-
Appium Flutter Driver offers advanced locating strategies
- Flutter Search: Which queries widgets present on the screen
- Semantics: Which locates widgets based on available names or tags
- Ancestor: Traverses the widget hierarchy
Checking widgets using the Flutter Inspector
Flutter provides a handy tool called Flutter Inspector to help visually inspect and check the widgets in your app. It simplifies locating the interactive elements of the application, thus facilitating the automation of Appium testing.
- It allows you to select any widget displayed by Flutter and copy its unique element locators such as accessibility_id. In this way, you can achieve precise targeting of the locator.
- The structure of the user interface can be confirmed by looking at the widget hierarchy and structure.
- The inspector outlines the selected widget in the app preview, which highlights the boundaries used to handle gestures and touches in Flutter. This helps to place the gesture correctly.
Flutter Inspector acts as a companion to help take automation workflows to the next level in Appium test automation.
The Flutter Inspector can be opened after launching the emulator by clicking on the Flutter Inspector icon in the right pane:
Let’s say I want to find the locator for the numbers 4 and 6, the operator ‘x’ and =, then I’ll click on the Toggle Select Mode Widget in the Flutter Inspector.
Next, I’ll click on the elements I want to rate, which will open the element structure as shown below:
From here you can capture the locator details and use them later in your test script.
As you can see, most of the elements use a text widget, so I’ll add a property valueKey
user output text to uniquely identify them and then build the application.
Updated code in main_screen.dart file.
Container(
alignment: Alignment.bottomRight,
child: Text(
controller.userOutput,
key:ValueKey("res"),
style: GoogleFonts.ubuntu(
fontWeight: FontWeight.bold,
color: themeController.isDark ? Colors.white : Colors.black,
fontSize: 60,
),
),
),
The file should look like the screenshot below:
Generating a Flutter application middleware
Now that our app is working well and we know how to use the Flutter Inspector to locate mobile elements, we’ll generate the Android version of our app. To do this, run the command below in the terminal:
flutter build apk --debug
You can also use the –profiles mode to create a build.
If you want to create an iOS build, you can use the commands below:
flutter build ios --debug
flutter build ios --profile
flutter build ios --simulator
You will see that the apk has been successfully built and is located in the location shown in the logs.
Now we will use this apk in our automation tests.
Using Appium to automate a Flutter application
We’ll use the use case below to demonstrate the automation:
- Open the Calculator application.
- Add two numbers.
- Confirm the result.
To start implementing the test scenario, we will first install the flutter driver using the command below:
appium driver install –source=npm appium-flutter-driver
You can confirm the installation using the command below:
appium driver list
Now we are ready to write the automation script for the calculator application. We created a Maven project in Eclipse and added Appium, flutter-finder and TestNG dependencies to the pom.xml file. The Flutter Finder helps you find elements in your app with its multiple methods.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>AppiumProject</groupId>
<artifactId>AppiumProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.9.0</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.appium/java-client -->
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>9.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.github.ashwithpoojary98/appium_flutterfinder_java -->
<dependency>
<groupId>io.github.ashwithpoojary98</groupId>
<artifactId>appium_flutterfinder_java</artifactId>
<version>1.0.5</version>
</dependency>
</dependencies>
</project>
We create a simple class to test our scenario:
package flutter;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.Test;
import io.appium.java_client.android.AndroidDriver;
import io.github.ashwith.flutter.FlutterFinder;
public class Flutter_Calc
AndroidDriver driver;
@BeforeTest
public void setUp() throws MalformedURLException
//Setting desired capabilities for the android device with details like device name, version,etc
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability("platformName", "android");
dc.setCapability("platformVersion","14.0");
dc.setCapability("deviceName","Pixel7_TestGrid");
dc.setCapability("automationName", "Flutter");
// //setting capability for application we want to test
dc.setCapability("app","/Users/macair/Documents/Selenium/app-debug.apk");
// //Instantiating Android Driver and using Appium server host and port
driver= new AndroidDriver(new URL("http://192.168.29.88:4723/wd/hub"), dc);
System.out.println("Created AppiumDriver");
@Test
public void multiply()
//Instantiating the FlutterFinder object and passing driver to it
FlutterFinder finder = new FlutterFinder(driver);
//Locating numbers, mathematical operator and equals button on the calculator app
finder.byText("4").click();
finder.byText("x").click();
finder.byText("7").click();
finder.byText("=").click();
String res1 = finder.byValueKey("res").getText();
System.out.println(res1);
@AfterTest
public void tearDown()
driver.quit();
Make sure your Appium server is running. You can run the same using the Terminal command:
appium -p 4723 --base-path /wd/hub
Once the Appium server is started, after executing the above test, we will see the execution happening in the emulator and the logs printed on the console.
And that’s how you can easily automate your Flutter app and use a single codebase to automate both iOS and Android apps.
Automating a Flutter App with TestGrid
TestGrid is a dedicated test orchestration platform that not only simplifies but also improves test automation at scale. TestGrid also offers Flutter Apps automation through its simple no-code feature. This feature not only simplifies the entire automation process, but also allows team members to be quickly involved in the automation. Let’s automate the same scenarios using TestGrid’s no-code automation.
-
After logging in to TestGrid, go to the Codeless tab.
2. Inside your module, go to Test Cases and click on Add Test Case With Scriptless.
3. Now add test case name and description and upload Flutter apk. Note that you can also use your iOS version.
4. Now select the device with which you want to perform the test and click on Start Writing Test Case.
5. Now, through TestGrid’s interactive user interface, select the action and corresponding elements for the test case steps. Alternatively, you can choose to start recording your actions so that they are automatically recorded. When you’re done, click the Save button.
6. Your test case is now ready to run and you can execute it using the Run button.
7. As you can see in the screenshot below, the correct execution logs for your work are displayed.
You can review the logs, make changes to your script based on the results, and rerun the test case.
With its powerful integrations, automated reporting, and customizable dashboards, TestGrid allows engineers to focus on improving the test coverage and performance of their Flutter applications. The platform takes care of the rest!
Conclusion
Appium enables end-to-end test automation for Flutter mobile apps by configuring the Appium Flutter Driver and Flutter Inspector. Flutter Driver handles unit and widget testing. Appium then thoroughly checks the UI, user journeys, localization, device integration and many other aspects. Robust selectors generated by Flutter Finder help target elements precisely. Integrations with solutions like TestGrid help monitor automation quality through dashboards.