Статьи

Как автоматизировать скриншоты с помощью fastlane

В сообществе разработчиков iOS fastlane в настоящее время является очень популярным инструментом. Взаимодействие с iTunes Connect занимает очень утомительную задачу и делает ее практически безболезненной за счет автоматизации большей части. Мы взглянем на общую концепцию fastlane и научимся делать скриншоты для всех устройств на всех языках с помощью одной команды.

«Ручная, повторяющаяся работа не стоит моего времени». Каждый программист думал об этом хотя бы раз в своей карьере. Однако большинство из нас не хотят тратить время на то, чтобы научиться правильно автоматизировать. Может быть, это потому, что мы выполняем эти задачи нечасто, или, может быть, потому, что мы не думаем, что у нас недостаточно времени, чтобы справиться с этим прямо сейчас.

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

Вот где приходит fastlane . Он автоматизирует ваши каналы распространения и сводит к минимуму взаимодействие с порталом разработчика и iTunes Connect, не выходя из командной строки, или полностью автоматизируется на сервере непрерывной интеграции.

Fastlane это не просто инструмент. На момент написания этой книги были собраны двенадцать инструментов, которые следуют философии Unix «Делай одно и делай хорошо». Конечно, они зависят друг от друга и взаимодействуют друг с другом.

Сам Fastlane является оболочкой для этих инструментов, позволяя разработчикам определять рабочие процессы, также известные как дорожки . Каждый рабочий процесс требует различных инструментов для запуска. Например, если вы хотите распространить предварительную сборку для своих тестировщиков, вам не нужно создавать скриншоты для App Store.

Прежде чем вы сможете начать использовать fastlane, вы должны убедиться, что у вас установлены инструменты командной строки Xcode. В командной строке выполните xcode-select --install чтобы установить их. Если он уже установлен, вы увидите ошибку.

Сам Fastlane является драгоценным камнем Ruby. В зависимости от вашей системы вам нужно запустить gem install fastlane или sudo gem install fastlane . Последнее необходимо, когда вы используете версию Ruby, предоставляемую OS X.

После установки необходимых компонентов вы должны инициализировать свой проект для использования fastlane. В папке вашего проекта запустите fastlane init из командной строки, чтобы запустить мастер интерактивной настройки. Мастер запросит у вас адрес электронной почты и, возможно, пароль, если его еще нет в цепочке для ключей. Мастер также определяет атрибуты вашего приложения, такие как имя и идентификатор , и проверяет портал разработчика и iTunes Connect, если он там уже есть. Если это не так, то он предлагает создать его для вас. Безболезненно.

Вы также можете настроить доставку на том же шаге. Этот инструмент позволяет вам загружать метаданные, снимки экрана и двоичный файл в iTunes Connect. Мы посмотрим на это в другом уроке.

В процессе установки в каталоге вашего проекта создается новая папка fastlane . Он содержит данные конфигурации, наиболее важным из которых является файл с именем Fastfile . Файл описывает дорожки, которые есть у fastlane. Вот полоса appstore по умолчанию.

1
2
3
4
5
6
7
8
desc «Deploy a new version to the App Store»
lane :appstore do
  match(type: «appstore»)
  snapshot
  gym
  deliver(force: true)
  frameit
end

Этот рабочий процесс или полоса делает следующее:

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

В этом конкретном уроке мы подробно рассмотрим второй шаг, снимок .

Почему вы должны автоматизировать скриншоты? Их легко сделать в симуляторе. Это может быть правдой, когда используется только одно устройство или один язык. Давайте сделаем математику. Если ваше приложение доступно на iPhone и iPad, у вас есть шесть размеров экрана (4,7 «, 5,5», 4 «, 3,5», iPad и iPad Pro). Предположим также, что ваше приложение доступно на двадцати языках, и вы делаете пять снимков экрана.

6 (устройства) × 20 (языки) x 5 (снимки экрана) = 600 снимков экрана

Теперь представьте, что вы должны взять их вручную. Это безумие. К счастью, есть снимок . Он автоматизирует создание снимков экрана с помощью средств автоматизации, предоставленных Apple. Еще лучше, начиная с Xcode 7, нам больше не нужно использовать JavaScript для автоматизации этого. Мы можем использовать Swift и UI тесты для этой задачи.

При установке fastlane снимок также устанавливается. Тем не менее, он не будет автоматически инициализировать снимок с ним при настройке нового проекта. Вам нужно запустить snapshot init в папке вашего проекта.

Это создает два файла в папке Snapfile , Snapfile и SnapshotHelper.swift . Вы должны добавить файл Swift к цели тестирования пользовательского интерфейса вашего проекта.

Добавление SnapshotHelperswift
Убедитесь, что вы добавили файл в цель тестов пользовательского интерфейса.

После добавления этого файла вам также необходимо использовать предоставленный снимок кода для сохранения снимков экрана. Вы можете использовать тестовый файл пользовательского интерфейса, сгенерированный XCode или создать отдельный только для скриншотов.

В функции setUp() замените XCUIApplication().launch() следующим кодом:

1
2
3
let app = XCUIApplication()
setupSnapshot(app)
app.launch()

Для ясности вы также можете переименовать testExample() , но убедитесь, что вы не удаляете префикс test имени функции.

Теперь пришло время записать шаги, которые вы предпринимаете для создания каждого из скриншотов. Вы также можете управлять приложением программно, но гораздо проще использовать функцию записи XCode и редактировать ее позже, чтобы соответствовать вашим потребностям.

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

Когда вы записываете простое взаимодействие, вы получаете код, который выглядит примерно так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
func testScreenshots() {
    let app = XCUIApplication()
    let masterNavigationBar = app.navigationBars[«Master»]
    let addButton = masterNavigationBar.buttons[«Add»]
    addButton.tap()
    addButton.tap()
         
    let tablesQuery = app.tables
    tablesQuery.staticTexts[«2016-04-12 08:43:40 +0000»].tap()
    app.navigationBars.matchingIdentifier(«Detail»).buttons[«Master»].tap()
    masterNavigationBar.buttons[«Edit»].tap()
    tablesQuery.buttons[«Delete 2016-04-12 08:43:39 +0000»].tap()
    tablesQuery.buttons[«Delete»].tap()
    masterNavigationBar.buttons[«Done»].tap()
}

Пример взят из стандартного шаблона приложения Master-Detail, который предоставляет Xcode. Сразу же вы можете увидеть проблему с этим кодом. Он использует определенные идентификаторы для взаимодействия с приложением. Если мы снова запустим тест пользовательского интерфейса, он потерпит неудачу, потому что метки времени отличаются.

На первом этапе мы можем использовать функцию, предоставляемую платформой UI Test, elementBoundByIndex(_:) . Это позволяет нам получить доступ к элементам, таким как кнопки и ячейки табличного представления, используя индекс. Это приводит к следующему коду:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
func testScreenshots() {
    let app = XCUIApplication()
    let masterNavigationBar = app.navigationBars[«Master»]
    let addButton = masterNavigationBar.buttons[«Add»]
    addButton.tap()
    addButton.tap()
         
    let tablesQuery = app.tables
    tablesQuery.cells.elementBoundByIndex(0).tap()
    app.navigationBars.matchingIdentifier(«Detail»).buttons[«Master»].tap()
    masterNavigationBar.buttons[«Edit»].tap()
    tablesQuery.cells.elementBoundByIndex(0).buttons.elementBoundByIndex(0).tap()
    tablesQuery.buttons[«Delete»].tap()
    masterNavigationBar.buttons[«Done»].tap()
}

У нас есть другая проблема, когда мы пытаемся запустить код на нескольких языках. Сбой, так как Master , Add и т. Д. Названы по-разному в каждом языке Мы также можем решить эту проблему с помощью elementBoundByIndex(_:) . Обратите внимание, что правая кнопка на панели навигации на самом деле имеет индекс 2 , что означает, что это третий элемент, потому что на панели навигации всегда есть скрытая кнопка возврата.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
func testScreenshots() {
    let app = XCUIApplication()
    let masterNavigationBar = app.navigationBars.elementBoundByIndex(0)
    let addButton = masterNavigationBar.buttons.elementBoundByIndex(2)
    addButton.tap()
    addButton.tap()
     
    let tablesQuery = app.tables
    tablesQuery.cells.elementBoundByIndex(0).tap()
    app.navigationBars.elementBoundByIndex(0).buttons.elementBoundByIndex(0).tap()
    masterNavigationBar.buttons.elementBoundByIndex(0).tap()
    let cell = tablesQuery.cells.elementBoundByIndex(0)
    cell.buttons.elementBoundByIndex(0).tap()
    cell.buttons.elementBoundByIndex(1).tap()
    masterNavigationBar.buttons.elementBoundByIndex(0).tap()
}

Есть еще один ярлык, который значительно облегчает доступ пользовательских элементов к тестам пользовательского интерфейса. Это свойство accessibilityIdentifier , определенное протоколом UIAccessibilityIdentification . Вы можете использовать его для поиска элементов с этим идентификатором, например, app.buttons.matchingIdentifier("awesomeButton").element . Идентификатор доступности не виден пользователю, даже когда у него включена доступность, и он не локализован.

После того, как вы настроили пользовательский интерфейс для работы с поддерживаемыми языками проекта, пришло время настроить снимок, чтобы сделать несколько снимков экрана. Это делается с помощью функции snapshot(_:) в вашем тесте пользовательского интерфейса. Вам также необходимо указать имя файла. Я лично использую пронумерованный префикс, такой как snapshot("1MasterView") или snapshot("2DetailView") чтобы было легче подсчитать, сколько скриншотов я уже сделал и автоматически отсортировать их. Если вам нужно дополнительное время, прежде чем делать снимок экрана, используйте функцию sleep(_:) .

Наконец, вам нужно указать снимок, какие устройства и языки он должен использовать. Это указано в Snapfile .

1
2
devices([«iPhone 6», «iPhone 6 Plus», «iPhone 4s»])
languages([«en-US», «de-DE»])

В этом примере я использую iPhone 6, iPhone 6 Plus и iPad в качестве устройств, а английский и немецкий — в качестве языков.

Чтобы запустить инструмент, вы выполняете snapshot из командной строки. В зависимости от размера вашего проекта и количества устройств и языков, создание снимков экрана может занять некоторое время. А пока вы можете размять ноги, выпить чашку кофе или просто посмотреть, как это работает.

По умолчанию снимки экрана хранятся в fastlane / screenshots , причем каждый язык имеет свою собственную подпапку и имена файлов с префиксом имени устройства. После того, как снимок сделан, он также генерирует файл HTML, чтобы легко просмотреть созданные снимки экрана.

Предварительный просмотр скриншотов
После того, как снимок сделан, он также генерирует файл HTML, чтобы легко просмотреть созданные снимки экрана.

Используя снимок , вы можете сократить время и усилия, необходимые для создания снимков экрана для вашего приложения, до доли, необходимой для выполнения этой задачи вручную. Конечно, этот инструмент гораздо более настраиваемый, потому что мы только слегка коснулись того, что может сделать снимок . Для получения дополнительной информации ознакомьтесь с документацией на GitHub. Вы также можете проверить мой видеокурс о fastlane, если хотите больше узнать об этом удивительном инструменте.