Modern QA2026Облачные фермы устройств
Join

Course09 Mobile & Cross-Platform Testing

Cutting-edge · Chapter 09

Облачные фермы устройств

Updated Jul 2026

Почему облачные фермы устройств необходимы

Тестирование на реальных устройствах в масштабе требует облачной инфраструктуры. Ни одна команда не способна поддерживать лабораторию из 200+ устройств на 15+ версиях ОС, обеспечивая их зарядку, обновление и подключение. Облачные фермы устройств предоставляют доступ по запросу к тысячам реальных устройств, устраняя бремя управления физическими устройствами.

Сравнение платформ

Функция BrowserStack Sauce Labs AWS Device Farm Firebase Test Lab
Реальные устройства 3 000+ 2 000+ Курируемый набор Устройства Google + популярные OEM
Эмуляторы/симуляторы Да Да Нет (только реальные) Да
Параллельное выполнение Без ограничений Зависит от плана 5-50 одновременно Зависит от плана
Поддержка Appium Полная Полная Полная Частичная
Playwright/Selenium Полная Полная Нет для мобильного веба Нет
Запись видео Да Да Да Да
Ограничение сети Да Да Ограниченно Ограниченно
Геолокация Да Да Нет Нет
Интеграция с CI Все основные Все основные AWS CodePipeline Firebase CLI
Модель ценообразования За пользователя/месяц За пользователя/месяц За устройство-минуту Бесплатный уровень + по использованию
Лучше всего для Широкое покрытие, веб + мобильные Корпоративные, комплаенс Команды на AWS Команды с фокусом на Android

Выбор платформы

Если ваша команда... Выбирайте Почему
Нуждается в веб- и мобильном тестировании BrowserStack или Sauce Labs Единая платформа для обоих
Работает на AWS и ограничена в бюджете AWS Device Farm Оплата поминутно, без подписки
В основном разрабатывает Android-приложения Firebase Test Lab Бесплатный уровень, глубокая интеграция с Android
Имеет корпоративные требования комплаенса Sauce Labs SOC 2 Type 2, HIPAA доступен
Нуждается в максимальном разнообразии устройств BrowserStack Самый большой каталог реальных устройств

Пример интеграции с BrowserStack

Рабочий процесс GitHub Actions

# .github/workflows/mobile-tests.yml
name: Mobile E2E Tests
on:
  push:
    branches: [main]

jobs:
  mobile-tests:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        include:
          - device: "iPhone 15"
            os_version: "18"
            platform: "ios"
          - device: "Samsung Galaxy S24"
            os_version: "14.0"
            platform: "android"
          - device: "Google Pixel 8"
            os_version: "14.0"
            platform: "android"

    steps:
      - uses: actions/checkout@v4

      - name: Upload app to BrowserStack
        run: |
          RESPONSE=$(curl -u "$BS_USER:$BS_KEY" \
            -X POST "https://api-cloud.browserstack.com/app-automate/upload" \
            -F "file=@./builds/app-release.apk")
          echo "APP_URL=$(echo $RESPONSE | jq -r '.app_url')" >> $GITHUB_ENV

      - name: Run Appium tests
        env:
          BROWSERSTACK_USER: ${{ secrets.BS_USER }}
          BROWSERSTACK_KEY: ${{ secrets.BS_KEY }}
          DEVICE: ${{ matrix.device }}
          OS_VERSION: ${{ matrix.os_version }}
        run: |
          pytest tests/mobile/ \
            --device="$DEVICE" \
            --os-version="$OS_VERSION" \
            --app-url="$APP_URL" \
            --junitxml=results-${{ matrix.device }}.xml

Конфигурация capabilities для BrowserStack

# conftest.py -- BrowserStack configuration
import os
from appium import webdriver
from appium.options.android import UiAutomator2Options
import pytest

@pytest.fixture
def bs_driver(request):
    """Create a BrowserStack Appium driver."""
    device = os.environ.get("DEVICE", "Samsung Galaxy S24")
    os_version = os.environ.get("OS_VERSION", "14.0")
    app_url = os.environ.get("APP_URL")

    options = UiAutomator2Options()
    options.set_capability("platformName", "Android")
    options.set_capability("appium:deviceName", device)
    options.set_capability("appium:platformVersion", os_version)
    options.set_capability("appium:app", app_url)

    # BrowserStack-specific capabilities
    options.set_capability("bstack:options", {
        "userName": os.environ["BROWSERSTACK_USER"],
        "accessKey": os.environ["BROWSERSTACK_KEY"],
        "projectName": "MyApp Mobile Tests",
        "buildName": f"Build-{os.environ.get('GITHUB_SHA', 'local')[:8]}",
        "sessionName": request.node.name,
        "debug": True,
        "networkLogs": True,
        "video": True,
        "appiumVersion": "2.6.0",
        "idleTimeout": 300,
    })

    driver = webdriver.Remote(
        command_executor="https://hub-cloud.browserstack.com/wd/hub",
        options=options,
    )
    yield driver

    # Mark test status in BrowserStack
    status = "passed" if request.node.rep_call.passed else "failed"
    driver.execute_script(
        f"browserstack_executor: {{\"action\": \"setSessionStatus\", "
        f"\"arguments\": {{\"status\": \"{status}\"}}}}"
    )
    driver.quit()

Firebase Test Lab для Android

Firebase Test Lab предлагает щедрый бесплатный уровень и глубокую интеграцию с экосистемой Android:

# Run Appium tests on Firebase Test Lab
gcloud firebase test android run \
  --type instrumentation \
  --app builds/app-release.apk \
  --test builds/app-test.apk \
  --device model=Pixel7,version=34 \
  --device model=oriole,version=33 \
  --timeout 10m \
  --results-bucket gs://my-test-results \
  --results-dir "run-$(date +%Y%m%d-%H%M%S)"

# Run a robo test (automatic exploration)
gcloud firebase test android run \
  --type robo \
  --app builds/app-release.apk \
  --device model=Pixel7,version=34 \
  --timeout 5m \
  --robo-directives "text:username_field=test@example.com,text:password_field=pass123"

Firebase Robo-тесты

Robo-тест Firebase автоматически обходит ваше приложение, нажимая кнопки и заполняя формы для обнаружения крашей. Это полезно как смоук-тест, потому что не требует написания тестового кода:

# .github/workflows/firebase-robo.yml
name: Firebase Robo Test
on:
  push:
    branches: [main]

jobs:
  robo-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: google-github-actions/auth@v2
        with:
          credentials_json: ${{ secrets.GCP_CREDENTIALS }}
      - uses: google-github-actions/setup-gcloud@v2

      - name: Run Robo test
        run: |
          gcloud firebase test android run \
            --type robo \
            --app builds/app-release.apk \
            --device model=Pixel7,version=34 \
            --device model=a]54x,version=34 \
            --timeout 5m

      - name: Check for crashes
        run: |
          RESULTS=$(gcloud firebase test android results describe --format json)
          CRASHES=$(echo "$RESULTS" | jq '.testExecutions[].testResults.crashCount')
          if [ "$CRASHES" != "0" ]; then
            echo "Robo test found crashes!"
            exit 1
          fi

AWS Device Farm

AWS Device Farm работает по модели оплаты за минуту без подписки, что делает его экономически эффективным для команд, запускающих тесты реже:

# Run tests on AWS Device Farm
import boto3

def create_test_run(project_arn, app_arn, test_package_arn):
    client = boto3.client('devicefarm', region_name='us-west-2')

    # Create a device pool (or use a curated one)
    run = client.schedule_run(
        projectArn=project_arn,
        appArn=app_arn,
        test={
            'type': 'APPIUM_PYTHON',
            'testPackageArn': test_package_arn,
        },
        devicePoolArn='arn:aws:devicefarm:us-west-2::devicepool:TOP_DEVICES',
        configuration={
            'jobTimeoutMinutes': 30,
        },
    )
    return run['run']['arn']

Лучшие практики для облачных ферм устройств

  1. Параллелизируйте агрессивно -- Облачные фермы тарифицируют за устройство-минуту. Запуск на 10 устройствах параллельно в течение 5 минут стоит столько же, сколько 1 устройство на 50 минут, но завершается в 10 раз быстрее.

  2. Используйте интеллектуальное распределение тестов -- Не все тесты нужно запускать на всех устройствах. Полную регрессию запускайте на устройствах Уровня 1, критические пути — на Уровне 2, смоук-тесты — на Уровне 3.

  3. Кэшируйте загрузки приложения -- Загружайте бинарный файл приложения один раз за сборку, затем ссылайтесь на него во всех запусках на устройствах.

  4. Включайте запись видео только при сбоях -- Запись видео создаёт накладные расходы. Включайте её для отладки упавших прогонов, а не для каждого успешного теста.

  5. Устанавливайте таймауты простоя -- Облачные устройства тарифицируются во время простоя. Устанавливайте агрессивные таймауты (3-5 минут) для предотвращения зависших сессий.

  6. Отмечайте сборки для трассируемости -- Включайте git SHA, имя ветки и номер PR в теги сборки, чтобы можно было соотнести результаты тестов с изменениями кода.

build_name = f"{os.environ.get('GITHUB_SHA', 'local')[:8]}-" \
             f"{os.environ.get('GITHUB_REF_NAME', 'dev')}"

Облачные фермы устройств — единственный практичный способ достичь широкого покрытия устройств для мобильных приложений. Первоначальные инвестиции в конфигурацию окупаются уверенностью в тестировании и предотвращением багов.