This section provides a comprehensive step-by-step guide to set up your environment for running Appium Flutter tests. Follow these instructions carefully to ensure a successful setup.
Before starting the setup, ensure you have the following installed on your system:
/Users/username/flutter
)export PATH="$PATH:/Users/username/flutter/bin"
flutter doctor
cd /path/to/appium_testing_poc
python3 -m venv test/appium/venv
# On macOS/Linux:
source test/appium/venv/bin/activate
pip install pytest pytest-html
pip install Appium-Python-Client
pip install appium-flutter-finder
# On Windows:
test/appium\venv\Scripts\activate
pip install pytest pytest-html
pip install Appium-Python-Client
pip install appium-flutter-finder
cd test/appium
pip install -r requirements.txt
npm install -g appium
appium driver install --source=npm appium-flutter-driver
pip install appium-flutter-finder==0.3.0
appium --version
export ANDROID_HOME=/Users/username/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/tools/bin
export PATH=$PATH:$ANDROID_HOME/platform-tools
# List available devices
avdmanager list avd
# Create a new AVD (if needed)
avdmanager create avd -n "Pixel_4_API_30" -k "system-images;android-30;google_apis;x86"
emulator -avd Pixel_4_API_30
adb devices
xcode-select --install
sudo xcodebuild -license accept
xcrun simctl list devices
open -a Simulator
xcrun simctl boot "iPhone 16 Plus"
cd /path/to/appium_testing_poc
flutter pub get
flutter build apk --debug
flutter build ios --debug --simulator
test/appium/conftest.py
:
# For Android
ANDROID_DEVICE_NAME = "emulator-5554" # Your actual device name
# For iOS
IOS_DEVICE_NAME = "iPhone 16 Plus" # Your actual device name
# Android APK path
ANDROID_APK_PATH = "/path/to/your/app-debug.apk"
# iOS app path
IOS_APP_PATH = "/path/to/your/Runner.app"
After completing the setup, verify everything is working:
flutter doctor
python --version
appium --version
adb devices
xcrun simctl list devices
Issue | Solution |
---|---|
Flutter not found | Add Flutter to PATH and restart terminal |
Python virtual environment not activated | Run source test/appium/venv/bin/activate |
Appium not installed | Run npm install -g appium |
Android emulator not starting | Check AVD list and create new AVD if needed |
iOS Simulator not available | Install Xcode and accept license |
Device not detected | Check USB debugging (Android) or simulator status (iOS) |
Here's a quick reference for the most common setup commands:
Task | Command | Description |
---|---|---|
Check Flutter | flutter doctor |
Verify Flutter installation and dependencies |
Activate Python venv | source test/appium/venv/bin/activate |
Activate the Python virtual environment |
Install Python deps | pip install -r requirements.txt |
Install required Python packages |
Install Appium | npm install -g appium |
Install Appium globally |
Install Flutter Driver | appium driver install --source=npm appium-flutter-driver |
Install Appium Flutter Driver |
List Android devices | adb devices |
Check connected Android devices/emulators |
List iOS devices | xcrun simctl list devices |
Check available iOS simulators |
Build Android app | flutter build apk --debug |
Build debug APK for Android |
Build iOS app | flutter build ios --debug --simulator |
Build debug app for iOS simulator |
Run Android tests | python -m pytest test_login.py -v --platform android |
Run tests on Android platform |
Run iOS tests | python -m pytest test_login.py -v --platform ios |
Run tests on iOS platform |
This project is a Proof-of-Concept (POC) designed to demonstrate a complete workflow for setting up and running automated tests for a Flutter application using Appium. It integrates Flutter (for the mobile app), Python with pytest
(for writing and running tests), and the Appium Flutter Driver to bridge the two.
The primary goal is to establish a reliable, repeatable process for mobile test automation and to document the solutions to common challenges encountered during setup.
You can execute your tests in two ways, depending on your workflow and environment:
.apk
(Android) or .app
(iOS) file in your Appium capabilities.'app': '/path/to/your/app.apk' # Android
'app': '/path/to/your/app.app' # iOS
appPackage
(Android) or bundleId
(iOS) in your capabilities.'appPackage': 'com.example.yourapp' # Android
'bundleId': 'com.example.yourapp' # iOS
Choose the method that fits your workflow and CI/CD setup.
appPackage
(Android) or bundleId
(iOS) in your Appium capabilities.UiAutomator2
for Android, XCUITest
for iOS).enableFlutterDriverExtension()
enabled.
The magic behind this testing setup is the appium-flutter-driver
. It's an Appium driver that allows you to automate Flutter applications by leveraging Flutter's own testing and debugging capabilities.
http://127.0.0.1:PORT/AUTH_CODE=/
. If the Appium driver tries to connect without this auth code, it gets an HTTP 302 Redirect
error. The easiest workaround for local testing is to disable this feature using the --disable-service-auth-codes
flag when running the Flutter app.
The project is organized to separate the Flutter application from the Python test suite.
lib/main.dart
The Flutter application is a simple, single-screen UI with input fields and a button. The most important aspect for testing is the use of ValueKey
on widgets. These keys provide stable, unique locators for Appium to find elements, which is far more reliable than finding by text or type.
// Example from lib/main.dart
TextFormField(
key: const ValueKey('phone_field'),
// ...
),
test/appium/
File / Directory | Description |
---|---|
run_tests.py |
A Python script that orchestrates the test run. It checks for dependencies (like a running Appium server) and uses pytest to execute the test files. It also generates an HTML report. |
conftest.py |
A core pytest file for setting up shared test fixtures. Defines both driver_android and driver_ios fixtures with proper Flutter driver configuration for both platforms. |
test_login.py |
Contains the actual test cases. Uses dynamic platform detection via pytest fixtures to support both Android and iOS. All 6 tests pass on both platforms. |
pom_pages/login_page_pom.py |
Implements the Page Object Model with robust retry logic. Centralizes element locators (finding by ValueKey ) and includes _find_element_with_retry() method to handle stale element references. |
requirements.txt |
Lists all the required Python packages including appium-flutter-finder==0.3.0 for proper Flutter element detection. |
run_flutter_appium_tests.sh |
An automated shell script that attempts to run the entire workflow. It is currently unreliable due to timing and process management issues with flutter run . It serves as a good example of the challenges in fully automating this process without more advanced tools. |
This is a step-by-step process to run the tests. Follow it exactly.
Ensure no old processes are running that could interfere. Open a terminal and run:
killall -9 dart flutter node appium || true
|| true
prevents an error if no processes are found.Make sure your Android emulator or iOS simulator is running and unlocked. Verify it's connected with:
adb devices # For Android
xcrun simctl list devices # For iOS
For iOS, you need to build the app first:
flutter build ios --debug --simulator # For iOS
flutter build apk --debug # For Android (optional, can use flutter run)
In a new terminal, navigate to the project root and run the app with service auth codes disabled:
flutter run --debug --disable-service-auth-codes
CRITICAL: Wait for the output and find the Dart VM Service URL. This is the most important step.
A Dart VM Service on sdk gphone64 arm64 is available at:
http://127.0.0.1:60693/
Leave this terminal running.
In another new terminal, start Appium:
appium
Sanity Check: Wait until you see the log message [Appium] Appium REST http interface listener started on http://0.0.0.0:4723
. If you get an EADDRINUSE
error, it means Appium is already running, which is fine.
In a final terminal, navigate to the project root, activate the virtual environment, and run the tests:
# Navigate to the project root first
cd /path/to/appium_testing_poc
# Activate venv
source test/appium/venv/bin/activate
# Go to tests directory
cd test/appium
# Run the tests for Android
python -m pytest test_login.py -v --platform android
# OR run the tests for iOS
python -m pytest test_login.py -v --platform ios
# OR run with HTML report
python -m pytest test_login.py -v --html=reports/report.html --self-contained-html --platform android
--platform android
--platform ios
--html=reports/report.html --self-contained-html
python -m pytest test_login.py -v --html=reports/report.html --self-contained-html --platform ios
Error Message | Cause | Solution |
---|---|---|
ElementNotFoundException or StaleElementReferenceException |
Flutter driver loses element references between tests. | SOLVED: The current implementation includes retry logic in login_page_pom.py that handles these exceptions gracefully with up to 3 retry attempts. |
Cannot connect to the Dart Observatory URL... |
The port forwarding is incorrect (mismatched port) or was not set up for the current Flutter session. | Stop and restart the process. Ensure you are using the current port from the flutter run output for your adb forward command. |
...Unexpected server response: 302 |
Flutter's Observatory requires a service auth code, and the driver is not providing it. | Run your app with the --disable-service-auth-codes flag. If the issue persists, update your appium-flutter-driver . |
adb: error: cannot bind listener: Address already in use |
The local port you are trying to use for forwarding is already occupied on your machine. | Use a different local port for forwarding. Example: adb forward tcp:7001 tcp:60693 . You would then need to update your Appium capabilities to point to port 7001 . |
[Appium] Error: listen EADDRINUSE... |
An Appium server is already running on the default port (4723). | This is not a fatal error. It just means you don't need to start a new Appium instance. Proceed with running your tests. |
Appium server is not running |
The test runner's check failed to find a running Appium server before executing tests. | Start the Appium server manually in a separate terminal with the appium command. |
NotYetImplementedError or TimeoutException |
Appium Flutter Driver is outdated or incompatible with your Flutter SDK. | Update the driver using:appium driver install --source=npm appium-flutter-driver |
Tests hang or fail unexpectedly | Old processes, stale builds, or environment issues. | Kill all old processes (killall -9 dart flutter node appium || true ), clean builds, and restart everything. |
flutter run
output for adb forward
. If mismatched, Appium cannot connect.appium-flutter-driver
is up to date and compatible with your Flutter SDK. If you see NotYetImplementedError
or TimeoutException
, update the driver using:appium driver install --source=npm appium-flutter-driver
automationName: "Flutter"
instead of "XCUITest"
for proper Flutter element detection.flutter build ios --debug --simulator
xcrun simctl boot "iPhone 16 Plus"
Info.plist
and Runner.entitlements
.For more detailed information and troubleshooting: