Run Patrol tests

What is Patrol?

Patrol is a powerful, open-source testing framework for Flutter apps. Patrol builds on top of Flutter’s existing test tooling to enable you to do previously impossible things like interacting with permission dialogs, notifications, WebViews, changing device settings, toggling Wi-Fi, and much more. More information can be found here.

Step 1: Build the app under test and the instrumentation app (see docs)

The Patrol uses a similar way of preparing the app and instrumentation app for both Platforms. At the end, you will receive 2 output files, which should be uploaded to the Mobitru before test execution.
Here is an example of build commands for Patrol sample app:

#prerequisites: flutter command is available in CLI

#1. clone project:

git clone https://github.com/leancodepl/patrol.git

#2. active patrol cli from root patrol:
dart pub global activate --source path packages/patrol_cli && patrol
export PATH="$PATH":"$HOME/.pub-cache/bin"

#3. build app and tests from "packages/patrol/example/":
flutter build apk --config-only
patrol build android --target integration_test/main_test.dart  --verbose

#output 2 apks are:
# 1. packages/patrol/example/build/app/outputs/apk/dev/debug/app-debug.apk - app_artifact
# 2. packages/patrol/example/build/app/outputs/apk/androidTest/dev/debug/app-debug-androidTest.apk - test_artifact

#prerequisites: flutter command is available in CLI

#1. clone project:
git clone https://github.com/leancodepl/patrol.git

#2. active patrol cli from root patrol:

dart pub global activate --source path packages/patrol_cli && patrol
export PATH="$PATH":"$HOME/.pub-cache/bin"

#3. prepare ios project from "packages/patrol/example/":
flutter build ios --config-only  --flavor dev integration_test/main_test.dart

#4. install pods from "packages/patrol/example/ios":
pod install --repo-update

#5. open project in Xcode and select a development team in app and tests targets. also you can specify custom bundle id

#6. build app and tests from "packages/patrol/example/":
patrol build ios --release --verbose --flavor dev --target integration_test/main_test.dart

#output 2 app are:

# 1. build/ios_integ/Build/Products/Release-dev-iphoneos/Runner.app (app under test)
# 2. build/ios_integ/Build/Products/Release-dev-iphoneos/RunnerUITests-Runner.app (test instrumentation app)

#can be converted to ipa using the following commands:

mkdir Payload
mv Runner.app Payload
zip -r Runner.zip Payload
mv Runner.zip Runner.ipat

Step 2: Upload the app and instrumentation app to the Mobitru

Upload your built app and instrumentation for Android (.apk files) or iOS (.ipa files) to the Mobitru using our REST API. Here is an example cURL request to upload the app:

curl --location --request POST 'https://app.mobitru.com/billing/unit/<BILLING_UNIT>/automation/api/v1/spaces/artifacts' \
--header 'x-File-Name: AppFlutter.apk' \
--header 'X-Content-Type: application/zip' \
--header 'Authorization: Bearer <ACCESS_KEY>' \
--form 'file=@"/path/to/app/file/app-flutter.apk"' \
--form 'checksum="None"'

Below you can find a sample of the response with an id of the uploaded app:

{
    "id": "b7b0aae5-a839-4c15-b6ba-98edb75d07a1",
    "name": "22d69718-59a9-40c6-809c-0e3d4a7313b7.apk",
    "realName": "AppFlutter.apk",
    "bid": "916f0549-4ddc-491a-9fe7-3f27597fd3b7",
    "wid": "0",
    "private": true,
    "uploadedBy": "test_user@epam.com",
    "uploadedAt": 1670264922,
    "verified": false,
    "target": "android",
    "contentType": "application/zip",
    "contentLength": 0,
    "href": "quarantine/22d69718-59a9-40c6-809c-0e3d4a7313b7.apk",
    "checksum": "None",
    "alias": "automation",
    "apk": null,
    "ipa": null
}

Step 5: Find and take a device

Find and take appropriate device using our APIs.

Here is an example of cURL request to find a device via API :

Android:

curl --location --request GET 'https://app.mobitru.com/billing/unit/<BILLING_UNIT>/automation/api/device/android?model=Pixel 6' \
--header 'Authorization: Bearer <ACCESS_KEY>'

iOS:

curl --location --request GET 'https://app.mobitru.com/billing/unit/<BILLING_UNIT>/automation/api/device/ios?version=16.2' \
--header 'Authorization: Bearer <ACCESS_KEY>'

Below you can find a sample of the response with capabilities for found devices:

Android:

[
    {
        "desiredCapabilities": {
            "platformName": "Android",
            "platformVersion": "12",
            "deviceName": "GOOGLE Pixel 6a",
            "udid": "26281JEGR04493"
        }
    },
    {
        "desiredCapabilities": {
            "platformName": "Android",
            "platformVersion": "12",
            "deviceName": "GOOGLE Pixel 6",
            "udid": "19161FDF600DJP"
        }
    },
    {
        "desiredCapabilities": {
            "platformName": "Android",
            "platformVersion": "13",
            "deviceName": "GOOGLE Pixel 6 Pro",
            "udid": "1A281FDEE007T3"
        }
    }
]


iOS:

[
    {
        "desiredCapabilities": {
            "platformName": "iOS",
            "platformVersion": "16.2",
            "deviceName": "IPHONE iPhone13,3",
            "udid": "00008101-00042D8A1190001E",
            "automationName": "XCUITest"
        }
    },
    {
        "desiredCapabilities": {
            "platformName": "iOS",
            "platformVersion": "16.2",
            "deviceName": "IPAD iPad12,1",
            "udid": "00008030-001E79460A10C02E",
            "automationName": "XCUITest"
        }
    },
    {
        "desiredCapabilities": {
            "platformName": "iOS",
            "platformVersion": "16.2",
            "deviceName": "IPHONE iPhone13,2",
            "udid": "00008101-001219601A51003A",
            "automationName": "XCUITest"
        }
    }
]

Here is an example of cURL request to take a device via API:

Android:

curl --location --request POST 'https://app.mobitru.com/billing/unit/<BILLING_UNIT>/automation/api/device/26281JEGR04493' \
--header 'Authorization: Bearer <ACCESS_KEY>'

iOS:

curl --location --request POST 'https://app.mobitru.com/billing/unit/<BILLING_UNIT>/automation/api/device/00008101-00042D8A1190001E' \
--header 'Authorization: Bearer <ACCESS_KEY>'

Below you can find a sample of the response with capabilities for the device:

Android:

{ 
    "desiredCapabilities": {
        "platformName": "Android",
        "platformVersion": "12",
        "deviceName": "GOOGLE Pixel 6a",
        "udid": "26281JEGR04493"
    }
}

iOS:

{
    "desiredCapabilities": {
        "platformName": "iOS",
        "platformVersion": "16.2",
        "deviceName": "IPHONE iPhone13,3",
        "udid": "00008101-00042D8A1190001E"
    }
}

Step 4: Run the tests

After uploading the built apps and taking a device, you can run the Patrol tests using API for Espresso (Android) or XCUITests (iOS).
Here is an example of cURL requests:

curl --location --request POST 'https://app.mobitru.com/billing/unit/<BILLING_UNIT>/automation/api/v1/tests/espresso' \
--header 'Authorization: Bearer <ACCESS_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "serial": "<device_UUID>",
    "app_artifact_id": "<app_apk_artifact_id>",
    "test_artifact_id": "<intrumentation_apk_artifact_id>",
    "runner_class":"pl.leancode.patrol.PatrolJUnitRunner"
}'


curl --location --request POST 'https://app.mobitru.com/billing/unit/<BILLING_UNIT>/automation/api/v1/tests/xcuitest' \
--header 'Authorization: Bearer <ACCESS_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "serial": "<device_uuid>",
    "app_artifact_id": "<app_ipa_artifact_id>",
    "test_artifact_id": "<instrumentation_ipa_artifact_id>",
    "resign":true
}'

More details regarding this can be found in Espresso and XCUITest docs.

Scroll to Top