Appium Flutter Testing on Sauce Labs
The appium-flutter-driver
. is now considered a legacy driver by Appium,
meaning no bug fixes or updates will be released. However, it can still be used when running tests on Sauce Labs.
We advise transitioning to the appium-flutter-integration-driver.
A guide on how to run tests on Sauce Labs using the new driver can be found here.
Sauce Labs supports testing Flutter apps on Android and iOS virtual and real devices with Appium by supporting the appium-flutter-driver
. The process to test Flutter apps with Appium involves an extra and important step, which is preprocessing your app. After that you can build it, upload it to Sauce Labs, configure your Appium capabilities and run your tests.
What You'll Need
- Familiarity with creating, signing and building Flutter apps.
- Familiarity writing and running Appium tests.
Preprocessing your Flutter App
The Appium Flutter Driver uses the Dart VM Service Protocol with extension ext.flutter.driver
, similar to Flutter Driver, to control the Flutter app-under-test (AUT). This needs to be enabled in the AUT before the app can be tested with Appium Flutter Driver and can be done by following the steps below:
- Open your Flutter project in your favorite IDE.
- In your
pubspec.yaml
file, add the following dependency:
#...
dev_dependencies:
test: any
flutter_test:
sdk: flutter
flutter_driver:
sdk: flutter
#...
Both libraries provide functions and APIs respectively to write tests for Flutter apps.
- Run the following command to install the
dev_dependencies
that you added in the previous step.
flutter pub get
- Now open the
main.dart
file in your Flutter project and add the following code statement.
import 'package:flutter_driver/driver_extension.dart';
This statement imports the driver_extension.dart
file from the flutter_driver
library and is the first step to enable the Flutter Driver extension.
- The
import
from the previous step provides anenableFlutterDriverExtension()
function that enables the Flutter Driver extension. Add the following code statement in the main.dart file of your Flutter project to enable it for your project.
void main() {
// This line enables the extension
enableFlutterDriverExtension();
runApp(const MyApp());
}
Check out the enableFlutterDriverExtension
function section to learn more about it's powers.
Building your Flutter App
After you have enabled the Flutter Driver extension, you can now build your app for testing. To do so, follow the steps below
- Open your Flutter project in your favorite IDE and or open a terminal in the root directory of your Flutter project.
- Determine for which device type (Android Emulator/Real Device or iOS Simulator/Real Device) you want to build your app for.
- Run one of the following commands
OS | Device Type | Build Command | Output Folder |
---|---|---|---|
Android | Emulator | flutter build apk --debug | {project-root}/build/app/outputs/flutter-apk/ |
Android | Real Device | flutter build apk --debug | {project-root}/build/app/outputs/flutter-apk/ |
iOS | Simulator | flutter build ios --simulator | {project-root}/build/ios/iphonesimulator/ |
iOS | Real Device | flutter build ipa --profile | {project-root}/build/ios/ipa/ |
For more information regarding the build modes (debug
, release
, profile
) for Flutter apps, see Flutter's build modes documentation.
Uploading your Flutter App to Sauce Labs
You can now upload the built apps with our REST API, or manually upload them to the preferred Data Center. See Manually Uploading an App for more information.
Configuring your Appium Capabilities
More information on how to write Appium tests for Flutter apps can be found in the Appium Flutter Driver repository. You can also find a sample Flutter app and tests in the Demo JS - Appium Flutter-repository.
We encourage you to use W3C capabilities for your tests. For more information on W3C capabilities, see W3C Capabilities.
Apps that have been built with Flutter 2 can use Appium 1 and Appium 2, while apps that have been built with Flutter 3 can only use Appium 2.
Android Emulators and iOS Simulators
- Java
- Node.js
- Python
- Ruby
- C#
- Android
- iOS
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformName", "android");
capabilities.setCapability("appium:platformVersion", "12");
capabilities.setCapability("appium:deviceName", "Google Pixel 6 Pro GoogleAPI Emulator");
// Mandatory for using the appium-flutter-driver
capabilities.setCapability("appium:automationName", "flutter");
capabilities.setCapability("appium:app", "storage:filename=flutter-counter-debug.apk");
HashMap<String, Object> sauceOptions = new HashMap<String, Object>();
sauceOptions.put("appiumVersion", "2.0.0-beta56");
capabilities.setCapability("sauce:options", sauceOptions);
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformName", "ios");
capabilities.setCapability("appium:platformVersion", "15.4");
capabilities.setCapability("appium:deviceName", "iPhone 13 Simulator");
// Mandatory for using the appium-flutter-driver
capabilities.setCapability("appium:automationName", "flutter");
capabilities.setCapability("appium:app", "storage:filename=flutter-counter-debug.zip");
HashMap<String, Object> sauceOptions = new HashMap<String, Object>();
sauceOptions.put("appiumVersion", "2.0.0-beta56");
capabilities.setCapability("sauce:options", sauceOptions);
- Android
- iOS
const capabilities = {
platformName: 'android',
'appium:platformVersion': '12',
'appium:deviceName': 'Google Pixel 6 Pro GoogleAPI Emulator',
// Mandatory for using the appium-flutter-driver
'appium:automationName': 'flutter',
'appium:app': 'storage:filename=flutter-counter-debug.apk',
'sauce:options': {
appiumVersion: '2.0.0-beta56'
}
}
const capabilities = {
platformName: 'ios',
'appium:platformVersion': '15.4',
'appium:deviceName': 'iPhone 13 Simulator',
// Mandatory for using the appium-flutter-driver
'appium:automationName': 'flutter',
'appium:app': 'storage:filename=flutter-counter-debug.zip',
'sauce:options': {
appiumVersion: '2.0.0-beta56'
}
}
- Android
- iOS
capabilities = {
"platformName" : "android",
"appium:platformVersion" : "12",
"appium:deviceName" : "Google Pixel 6 Pro GoogleAPI Emulator",
# Mandatory for using the appium-flutter-driver
'appium:automationName': 'flutter',
'appium:app': 'storage:filename=flutter-counter-debug.apk',
"sauce:options" : {
"appiumVersion" : "2.0.0-beta56"
}
}
capabilities = {
"platformName" : "ios",
"appium:platformVersion" : "15.4",
"appium:deviceName" : "iPhone 13 Simulator",
# Mandatory for using the appium-flutter-driver
'appium:automationName': 'flutter',
'appium:app': 'storage:filename=flutter-counter-debug.zip',
"sauce:options" : {
"appiumVersion" : "2.0.0-beta56"
}
}
- Android
- iOS
capabilities = {
"platformName" => "android",
"appium:platformVersion" => "12",
"appium:deviceName" => "Google Pixel 6 Pro GoogleAPI Emulator",
# Mandatory for using the appium-flutter-driver
'appium:automationName' => 'flutter',
'appium:app' => 'storage:filename=flutter-counter-debug.apk',
"sauce:options" => {
"appiumVersion" => "2.0.0-beta56"
}
}
capabilities = {
"platformName" => "ios",
"appium:platformVersion" => "15.4",
"appium:deviceName" => "iPhone 13 Simulator",
# Mandatory for using the appium-flutter-driver
'appium:automationName'=> 'flutter',
'appium:app' => 'storage:filename=flutter-counter-debug.zip',
"sauce:options" => {
"appiumVersion" => "2.0.0-beta56"
}
}
- Android
- iOS
AppiumOptions capabilities = new AppiumOptions();
capabilities.AddAdditionalCapability("platformName", "android");
capabilities.AddAdditionalCapability("appium:platformVersion", "12");
capabilities.AddAdditionalCapability("appium:deviceName", "Google Pixel 6 Pro GoogleAPI Emulator");
// Mandatory for using the appium-flutter-driver
capabilities.AddAdditionalCapability("appium:automationName", "flutter");
capabilities.AddAdditionalCapability("appium:app", "storage:filename=flutter-counter-debug.apk");
HashMap<String, Object> sauceOptions = new Dictionary<string, object>();
sauceOptions.Add("appiumVersion", "2.0.0-beta56");
capabilities.AddAdditionalCapability("sauce:options", sauceOptions);
AppiumOptions capabilities = new AppiumOptions();
capabilities.AddAdditionalCapability("platformName", "ios");
capabilities.AddAdditionalCapability("appium:platformVersion", "15.4");
capabilities.AddAdditionalCapability("appium:deviceName", "iPhone 13 Simulator");
// Mandatory for using the appium-flutter-driver
capabilities.AddAdditionalCapability("appium:automationName", "flutter");
capabilities.AddAdditionalCapability("appium:app", "storage:filename=flutter-counter-debug.zip");
HashMap<String, Object> sauceOptions = new Dictionary<string, object>();
sauceOptions.Add("appiumVersion", "2.0.0-beta56");
capabilities.AddAdditionalCapability("sauce:options", sauceOptions);
Real Devices
- Java
- Node.js
- Python
- Ruby
- C#
- Android
- iOS
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformName", "android");
// W3C Protocol is mandatory for Appium 2.0
capabilities.setCapability("appium:platformVersion", "12");
capabilities.setCapability("appium:deviceName", "Google Pixel 6");
// Mandatory for Appium 2.0
capabilities.setCapability("appium:automationName", "flutter");
capabilities.setCapability("appium:app", "storage:filename=flutter-counter-debug.apk");
HashMap<String, Object> sauceOptions = new HashMap<String, Object>();
// appiumVersion is mandatory to use Appium 2.0 on Sauce Labs
sauceOptions.put("appiumVersion", "2.0.0");
capabilities.setCapability("sauce:options", sauceOptions);
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformName", "ios");
// W3C Protocol is mandatory for Appium 2.0
capabilities.setCapability("appium:platformVersion", "16");
capabilities.setCapability("appium:deviceName", "iPhone 14");
// Mandatory for Appium 2.0
capabilities.setCapability("appium:automationName", "flutter");
capabilities.setCapability("appium:app", "storage:filename=flutter-counter-debug.ipa");
HashMap<String, Object> sauceOptions = new HashMap<String, Object>();
// appiumVersion is mandatory to use Appium 2.0 on Sauce Labs
sauceOptions.put("appiumVersion", "2.0.0");
capabilities.setCapability("sauce:options", sauceOptions);
- Android
- iOS
const capabilities = {
platformName: 'android',
// W3C Protocol is mandatory for Appium 2.0
'appium:platformVersion': '12',
'appium:deviceName': 'Google Pixel 6',
// Mandatory for Appium 2.0
'appium:automationName': 'flutter',
'appium:app': 'storage:filename=flutter-counter-debug.apk',
'sauce:options': {
// appiumVersion is mandatory to use Appium 2.0 on Sauce Labs
appiumVersion: '2.0.0'
}
}
const capabilities = {
platformName: 'ios',
// W3C Protocol is mandatory for Appium 2.0
'appium:platformVersion': '16',
'appium:deviceName': 'iPhone 14',
// Mandatory for Appium 2.0
'appium:automationName': 'flutter',
'appium:app': 'storage:filename=flutter-counter-debug.ipa',
'sauce:options': {
// appiumVersion is mandatory to use Appium 2.0 on Sauce Labs
appiumVersion: '2.0.0'
}
}
- Android
- iOS
capabilities = {
"platformName" : "android",
# W3C Protocol is mandatory for Appium 2.0
"appium:platformVersion" : "12",
"appium:deviceName" : "Google Pixel 6",
# Mandatory for Appium 2.0
'appium:automationName': 'flutter',
'appium:app': 'storage:filename=flutter-counter-debug.apk',
"sauce:options" : {
# appiumVersion is mandatory to use Appium 2.0 on Sauce Labs
"appiumVersion" : "2.0.0"
}
}
capabilities = {
"platformName" : "ios",
# W3C Protocol is mandatory for Appium 2.0
"appium:platformVersion" : "16",
"appium:deviceName" : "iPhone 14",
# Mandatory for Appium 2.0
'appium:automationName': 'flutter',
'appium:app': 'storage:filename=flutter-counter-debug.ipa',
"sauce:options" : {
# appiumVersion is mandatory to use Appium 2.0 on Sauce Labs
"appiumVersion" : "2.0.0"
}
}
- Android
- iOS
capabilities = {
"platformName" => "android",
# W3C Protocol is mandatory for Appium 2.0
"appium:platformVersion" => "12",
"appium:deviceName" => "Google Pixel 6",
# Mandatory for Appium 2.0
'appium:automationName' => 'flutter',
'appium:app' => 'storage:filename=flutter-counter-debug.apk',
"sauce:options" => {
# appiumVersion is mandatory to use Appium 2.0 on Sauce Labs
"appiumVersion" => "2.0.0"
}
}
capabilities = {
"platformName" => "ios",
# W3C Protocol is mandatory for Appium 2.0
"appium:platformVersion" => "16",
"appium:deviceName" => "iPhone 14",
# Mandatory for Appium 2.0
'appium:automationName'=> 'flutter',
'appium:app' => 'storage:filename=flutter-counter-debug.ipa',
"sauce:options" => {
# appiumVersion is mandatory to use Appium 2.0 on Sauce Labs
"appiumVersion" => "2.0.0"
}
}
- Android
- iOS
AppiumOptions capabilities = new AppiumOptions();
capabilities.AddAdditionalCapability("platformName", "android");
// W3C Protocol is mandatory for Appium 2.0
capabilities.AddAdditionalCapability("appium:platformVersion", "12");
capabilities.AddAdditionalCapability("appium:deviceName", "Google Pixel 6");
// Mandatory for Appium 2.0
capabilities.AddAdditionalCapability("appium:automationName", "flutter");
capabilities.AddAdditionalCapability("appium:app", "storage:filename=flutter-counter-debug.apk");
HashMap<String, Object> sauceOptions = new Dictionary<string, object>();
// appiumVersion is mandatory to use Appium 2.0 on Sauce Labs
sauceOptions.Add("appiumVersion", "2.0.0");
capabilities.AddAdditionalCapability("sauce:options", sauceOptions);
AppiumOptions capabilities = new AppiumOptions();
capabilities.AddAdditionalCapability("platformName", "ios");
// W3C Protocol is mandatory for Appium 2.0
capabilities.AddAdditionalCapability("appium:platformVersion", "16");
capabilities.AddAdditionalCapability("appium:deviceName", "iPhone 14");
// Mandatory for Appium 2.0
capabilities.AddAdditionalCapability("appium:automationName", "flutter");
capabilities.AddAdditionalCapability("appium:app", "storage:filename=flutter-counter-debug.ipa");
HashMap<String, Object> sauceOptions = new Dictionary<string, object>();
// appiumVersion is mandatory to use Appium 2.0 on Sauce Labs
sauceOptions.Add("appiumVersion", "2.0.0");
capabilities.AddAdditionalCapability("sauce:options", sauceOptions);