Appium Flutter POC - Comprehensive Documentation

Author: Belal Ashraf | Sr. Flutter Developer (Android, iOS, Web)

Version: 4.0

Date: July 14, 2025

Status: ✅ Fully Working - Android & iOS


💡 Environment Setup Guide
This section contains all the detailed steps required to set up your environment for running Appium Flutter tests.
Click below to expand / collapse the full setup instructions.
Environment Setup Guide

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.

2.1 Prerequisites

Before starting the setup, ensure you have the following installed on your system:

  • Flutter SDK (latest stable version)
  • Python 3.8+ with pip
  • Node.js (for Appium)
  • Android Studio (for Android development)
  • Xcode (for iOS development, macOS only)
  • Java Development Kit (JDK) 8 or higher

2.2 Step-by-Step Setup Instructions

Step 1: Install Flutter SDK

  1. Download Flutter SDK from flutter.dev
  2. Extract to a desired location (e.g., /Users/username/flutter)
  3. Add Flutter to your PATH:
    export PATH="$PATH:/Users/username/flutter/bin"
  4. Run Flutter doctor to verify installation:
    flutter doctor
  5. Install any missing dependencies reported by Flutter doctor

Step 2: Install Python Dependencies

  1. Navigate to the project directory:
    cd /path/to/appium_testing_poc
  2. Create a Python virtual environment:
    python3 -m venv test/appium/venv
  3. Activate the virtual environment and install all the required Python packages:
    
    # 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
                                
  4. Install required Python packages:
    cd test/appium
    pip install -r requirements.txt

Step 3: Install Appium and Drivers

  1. Install Appium globally:
    npm install -g appium
  2. Install Appium Flutter Driver:
    appium driver install --source=npm appium-flutter-driver
  3. Install Appium Flutter Finder:
    pip install appium-flutter-finder==0.3.0
  4. Verify Appium installation:
    appium --version

Step 4: Android Setup

  1. Install Android Studio and Android SDK
  2. Set up Android environment variables:
    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
  3. Create an Android Virtual Device (AVD):
    # 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"
  4. Start the Android emulator:
    emulator -avd Pixel_4_API_30
  5. Verify device connection:
    adb devices

Step 5: iOS Setup (macOS only)

  1. Install Xcode from the Mac App Store
  2. Install Xcode Command Line Tools:
    xcode-select --install
  3. Accept Xcode license:
    sudo xcodebuild -license accept
  4. Install iOS Simulator:
    xcrun simctl list devices
  5. Start iOS Simulator:
    open -a Simulator
  6. Boot a specific device:
    xcrun simctl boot "iPhone 16 Plus"

Step 6: Build the Flutter App

  1. Navigate to the project root:
    cd /path/to/appium_testing_poc
  2. Get Flutter dependencies:
    flutter pub get
  3. Build the app for Android:
    flutter build apk --debug
  4. Build the app for iOS:
    flutter build ios --debug --simulator

Step 7: Configure Test Environment

  1. Update device names in 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
  2. Update app paths if needed:
    # Android APK path
    ANDROID_APK_PATH = "/path/to/your/app-debug.apk"
    
    # iOS app path
    IOS_APP_PATH = "/path/to/your/Runner.app"

2.3 Verification Steps

After completing the setup, verify everything is working:

  1. Flutter: flutter doctor
  2. Python: python --version
  3. Appium: appium --version
  4. Android: adb devices
  5. iOS: xcrun simctl list devices

2.4 Common Setup Issues and Solutions

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)
💡 Pro Tip: Keep your development environment updated. Regularly update Flutter, Python packages, and Appium drivers to avoid compatibility issues.

2.5 Quick Setup Reference

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

1. Project Overview

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.

✅ VERIFIED WORKING: All 6 test cases pass on both Android and iOS platforms with the current implementation.

2. App Under Test:

You can execute your tests in two ways, depending on your workflow and environment:

Choose the method that fits your workflow and CI/CD setup.

You can also test any existing app already installed on your device—even if it's not your own—by specifying its appPackage (Android) or bundleId (iOS) in your Appium capabilities.
However: For non-Flutter apps, or Flutter apps you don't own (or not built in debug mode with the driver extension), you must use the native drivers (UiAutomator2 for Android, XCUITest for iOS).
Appium Flutter Driver only works for your own Flutter apps built in debug mode with enableFlutterDriverExtension() enabled.

3. Understanding the Appium Flutter Driver

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.

Flutter Driver -vs- Native Drivers (XCUITest/UiAutomator2):
For deep dive on the differences between Appium Flutter Driver and Native Drivers (XCUITest/UiAutomator2), when to use each, and the pros and cons of each, check this link:
https://claude.ai/share/d686ec26-d483-4a89-9381-7dd77de2ea77

Key Concepts

Key takeaway: The entire process relies on Appium successfully connecting to the Dart VM Service's WebSocket. Any issue with port forwarding, auth codes, or driver versions will break this connection.

4. Code Documentation and File Structure

The project is organized to separate the Flutter application from the Python test suite.

Flutter App: 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 Suite: 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.

5. Steps to Execute Tests

This is a step-by-step process to run the tests. Follow it exactly.

  1. Clean Slate: Kill All Old Processes

    Ensure no old processes are running that could interfere. Open a terminal and run:

    killall -9 dart flutter node appium || true
    The || true prevents an error if no processes are found.
  2. Start Emulator/Device

    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
  3. Build the App (if needed)

    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)
  4. Start the Flutter App

    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.

  5. Start the Appium Server

    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.

  6. Activate Python Environment and Run Tests

    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
    Cross-Platform Testing:
    • Android: --platform android
    • iOS: --platform ios
    • HTML Report: --html=reports/report.html --self-contained-html
    • Combined: python -m pytest test_login.py -v --html=reports/report.html --self-contained-html --platform ios

6. Troubleshooting & Platform-Specific Guidance

6.1 General Troubleshooting

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.

6.2 Android-Specific Issues

6.3 iOS-Specific Issues

✅ iOS CONFIGURATION FIXED: The current implementation uses the correct Flutter driver configuration for iOS, which resolves most iOS-specific issues.

7. Official Documentation References

For more detailed information and troubleshooting:

💡 Pro Tip: When encountering issues not covered in this POC documentation, the official Appium and Flutter driver documentation are excellent resources for troubleshooting and advanced configurations.