Fastlaneでアプリのスクリーンショットを自動化してみた


はじめに

1つ前の記事で、FastlaneでXCTestを自動化するという記事を書いたのですが、今回はその続きでアプリのスクリーンショットを自動化する記事を書いてみました。

Fastlaneをこれから導入するという方は、Fastlane導入については前記事をご参照ください。
今回はsnapshotを撮るところだけに焦点を当てていきます。

あと、前提としてプロジェクトにXCUITestは導入されている前提で進めます。

この記事で学べること

  • snapshotとは?
  • アプリのスクショの自動化(スナップショット)
  • スクショ自動化のための細かいオプション

Snapshot導入

fastlaneのsnapshotとは

アプリのスクリーンショットを自分で実機やシュミレーターを操作しながら取得する作業を自動化してくれるツールです。

スマホアプリ開発において「色々な大きさの機種のスクショを全画面取得せよ!」なんていうミッションは、よく課せられると思います。
そこで、このツールを導入することで作業が自動化され、マンパワーとコスト削減につながります。

導入してみる

snapfileの作成

bundle exec fastlane snapshot init

を実行すると、/fastlaneにSnapfileSnapshotHelper.swiftが生成されます。

SnapshotHelper.swiftをXCUITestに追加

生成されたSnapshotHelper.swiftをドラッグアンドドロップで、プロジェクトのXCUITestの直下に追加します。
こんな感じです。

photo1.png

テストコードに初期化処理を追加

setupSnapshot(app)をアプリ起動前に追加します。
スクリーンショットを取得したいタイミングでsnapshot("image名")を追加します。

func testLogin() throws {

    let app = XCUIApplication()
    setupSnapshot(app)
    app.launch()

    let loginPage = LoginPage(app: app)
    snapshot("ログイン画面")
    XCTAssertTrue(loginPage.pageTitle.identifier == "ログイン画面")

    loginPage
        .typeUserId("123456")
        .typePassword("123456")
        .tapLoginButton()

    let memberListPage = MemberListPage(app: app)
    snapshot("メンバー一覧")
    XCTAssertTrue(memberListPage.viewController.exists)
}

Snapfileを編集して最適化する

僕が使っているのはこの辺のパラメーターです。より詳しい情報はこちらにあります。

// テストしたいデバイス一覧
devices([
  "iPhone 8"
  # "iPhone 8 Plus",
  # "iPhone SE",
  # "iPhone X",
  # "iPad Pro (12.9-inch)",
  # "iPad Pro (9.7-inch)",
  # "Apple TV 1080p",
  # "Apple Watch Series 6 - 44mm"
])

// テスト実行の時に使用する言語一覧
languages(["ja-JP"])

// スクリーンショットをどこに保存するか
output_directory("./screenshots")

// スクリーンショット取得時に前回取得した分を破棄するかどうか
clear_previous_screenshots(true)

// 自動実行するテスト(スクリーンショット取得用メソッド)を個別指定可能
only_testing(["Switf5UITestTrainUITests/Switf5UITestTrainUITests/testLogin"])

スクリーンショットを取得する

ここまでで準備は完了です。あとは以下のコマンドを叩いてスクリーンショットを取得するのみ!

bundle exec fastlane snapshot run

こんな感じで緑のハートが出力されていれば成功です。

+----------+-------+
| snapshot results |
+----------+-------+
| Device   | ja-JP |
+----------+-------+
| iPhone 8 |  💚   |
+----------+-------+

終わったタイミングでHTMLファイルが生成されてブラウザで開かれるので、完了タイミングはわかります。
.png形式のファイルも指定したディレクトリに保存されているはずです。

注意点・ハマったポイント

スナップショット取得のためのテストが失敗(エラー)になると厄介

テスト自体が失敗されると、再ビルド→再テスト(スクショ取得)を複数回、繰り返します。
そのため、プロジェクトによっては、終了までに膨大な時間がかかります。

対策としては、

  • only_testingなどを活用して無駄なテストが実行されないようにする
  • snapshot取得テストの前に、snapshot取得で使うテストを、通常の自動テストですべて成功するか確認してから開始する

などが挙げられます。

取得したスナップショットの.pngファイルは順不同で保存されるので画面などがバラバラになってしまう

例えば1画面で複数のスクショが必要な場合、保存されるときはその関連性がないので、保存順がバラバラになります。
なので、後で見たときにどのスクショがどこにあるかわからなくなります。

なので名前をつけるときは、画面名をただ指定するよりは、"画面IDなど_画面名"にして、関連性のあるスクショがまとまって出力されるようにしたほうがいいと思います。

おわりに

今回、プロジェクトでスクショを撮るのを自動化したいということで、色々調べながらやってみました。
1回覚えてしまえば色々なプロジェクトで活用できるので、便利だなと思いました。