company_banner

Python-установщик Android-сборок из TeamCity своими руками


    Аудитория


    QA-инженеры, тестировщики мобильных приложений, автоматизаторы.


    Проблема


    Во время тестирования приложений под Android (не только, но далее речь пойдет только про данную платформу), приходится устанавливать множество сборок тестируемого продукта / продуктов. Этот процесс отнимает время и силы, которые эффективнее потратить на поиск багов.


    В настоящей статье мы рассмотрим существующее решение, напишем свое на Python и сравним их.


    Готовое решение


    Пожалуй, самое популярное на данный момент решение этой проблемы предоставляет сервис Crashlytics, включающий установщик Beta.


    Рассмотрим типичный процесс инсталляции приложения при помощи Crashlytics Beta:


    • Находим иконку Beta (1) → делаем тап (2) = запускается приложение.
    • Находим нужный проект (3) → делаем тап (4) = открывается экран со списком сборок.
    • Находим нужную сборку (5) → делаем тап «Download» (6) = загружается установочный файл на устройство.
    • Отображается экран с предложение установить приложение → тап «Установить» (7) = отображается экран установки.
    • Находим установленное приложение (8) → делаем тап (9) = приложение запускается; готово для тестирования.

    Итак, для инсталляции и запуска одной сборки приложения при помощи Crashlytics Beta необходимо совершить, в общей сложности, минимум девять действий. Будем ориентироваться на эти показатели и постараемся создать установщик, требующий для решения аналогичных задач, меньшее количество действий.


    Кастомное решение


    В качестве языка программирования выберем Python, т. к. он подходит для нашей задачи и является весьма популярным, в том числе и среди QA-инженеров.
    Для взаимодействия с Android будем использовать adb, входящий в стандартный пакет Android SDK.
    Для скачивания файлов — Wget.
    В нашем случае сборки осуществляются в TeamCity.


    Теперь перейдем к написанию кода.


    Первым делом импортируем в проект модуль subprocess, он необходим для выполнения команд wget и adb.


    import subprocess

    Добавим необходимые настройки для Wget.


    settings = {'user': '—user=логин_аккаунта_teamcity',
                'password': '—password=пароль_аккаунта_teamcity',
                'way': 'путь_куда_будут_скачиваться_сборки'}

    Устанавливать приложения будем по номеру сборки, поэтому научим скрипт спрашивать этот параметр.


    number = input('Укажите № сборки: ')

    Допустим, что нам необходимо устанавливать сразу две сборки: тестовую и боевую. Будем скачивать их из TeamCity. Для этого узнаем полный путь до файлов, открыв страницу сервиса и отыскав сборки в артефактах. URL до сборок будет выглядеть приблизительно так:


    https://teamcity.mysite.com/repository/app/номер_сборки/тип_сборки/myapp-номер_сборки-тип_сборки.apk

    В адресе вместо номера сборки вы можете увидеть id, например, /1234:id/. Здесь мы будем указывать не id, а номер сборки.


    Напишем функцию для скачивания заданных сборок.


    def download(type_b):
        url = 'http://teamcity.mysite.com/repository/app/{0}/{1}/myapp-{0}-{1}.apk'.format(number, type_b) 
    
        # Если файла нет — скачиваем, если есть, но не изменился — ничего не делаем, 
        # если есть и изменился — перезаписываем
    
        subprocess.check_output(['wget',
                                 '-N',
                                 '--cache=off',
                                 '--progress=bar',
                                 settings['user'],
                                 settings['password'],
                                 '-P',
                                 settings['way'],
                                 url])

    Напишем функцию для установки и запуска приложений. Сначала удаляем ранее установленные сборки. Не забываем, что если хотя бы одного приложения нет на устройстве – скрипт завершится с ошибкой. Чтобы избежать этого, будем игнорировать ошибки.


    В данном воображаемом примере два пакета:


    • com.myapp.prod
    • com.myapp.test

    Стартовые активности:


    • com.myapp.prod/com.myapp.StartActivity
    • com.myapp.test/com.myapp.StartActivity

    У вас имена пакетов и активностей будут другими.


    def install(type_b):
        try:
            # Удаляем старую сборку, указав package name
            subprocess.check_output(['adb', 'uninstall', 'com.myapp.{0}'.format(type_b)])
    
        except:
            # Если старой сборки нет — игнорируем ошибку.
            pass
    
        finally:
            # Устанавливаем новую сборку
            subprocess.check_output(['adb', 'install', '{0}/myapp-{1}-{2}.apk'.format(settings['way'], number, type_b)])
    
            # Запускаем новую сборку, указав activity name
            subprocess.check_output(['adb', 'shell', 'am', 'start', 'com.myapp.{0}/com.myapp.StartActivity'.format(type_b)])
    
            print('(^_^) Сборка ({0}-{1}) установлена и запущена.'.format(number, type_b))

    Все необходимы функции написаны. Теперь их можно применить.
    Дополнительно добавим обработчик случая, когда заданной сборки нет в TeamCity.


    while True:
        try:
            # Скачиваем сборку, смотрящую на боевой сервер
            download('prod')
    
            # Скачиваем сборку, смотрящую на тестовый сервер
            download('test')
    
        except Exception:
            # В случае ошибки — снова запрашиваем номер сборки
            number = input('¯\_(ツ)_/¯ Такой сборки нет.\nУкажите другой №: ')
    
        else:
            print('Начинаю установку…')
    
            # Устанавливаем и запускаем боевую сборку
            install('prod')
    
            # Устанавливаем и запускаем тестовую сборку
            install('test')
    
            # В случае успеха — немного Гомера Симпсона для хорошего настроения
            print('Уху! (_8(|)\n')
            break

    Скрипт готов. Сохраняем его, например, под именем installer.py
    Добавляем алиас, например, alias inst='python ~/scripts/installer.py'


    Проверка


    Итак, для установки одной сборки при помощи Crashlytics Beta необходимо совершить 9 действий. Для сравнения измерим данный показатель у скрипта.


    • Запускаем скрипт командой inst (1) = отображается предложение задать номер сборки.
    • Задаем номер сборки (2) = удаляются старые сборки; скачиваются, устанавливаются и запускаются новые. Приложение готово для тестирования.

    Результат


    Beta (1 сборка) — 9 действий (не учитывая удаление старых сборок).
    Свой скрипт (сколько угодно сборок) — 2 действия.


    Дополнительным бонусом кастомного решения является то, что оно масштабируется (добавление установки нескольких продуктов на ряд устройств и т. д.), а также легко адаптируется под задачи автоматического тестирования.


    Источники


    Mail.Ru Group

    856,00

    Строим Интернет

    Поделиться публикацией

    Похожие публикации

    Комментарии 1

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое