Fastlane Snapshotを使ってスクショ撮影を自動化する

※fastlaneの初期化は済んでいる想定です
↓この方の記事がとても分かりやすいので先にご覧ください！
[FastlaneとGitlabRunnerでCI/CDパイプラインを構築する](https://qiita.com/ShionKoga/items/47a3b2c084a76aa218cb)
 
#  はじめに

iosアプリをApp Storeに配信するとなると
アプリのビルドやその他諸々の情報だけでなく
アプリケーションのスクリーンショットを撮影して
併せてAppStoreにアップロードしなければなりません

>fastlane [**Snapshot**](https://docs.fastlane.tools/actions/snapshot/)は
App Storeのために異なるデバイスタイプと言語用にローカライズされた
iOS、tvOS、およびwatchOSのスクリーンショットを生成し
fastlane [**Deliver**](https://docs.fastlane.tools/actions/deliver/)を使用してAppStoreConnectにアップロードすることができます

アップデートの度にいちいち手動でスクショなんか撮ってられないですよね
[**Snapshot**](https://docs.fastlane.tools/actions/snapshot/)はその悩みを解決してくれます

その手順を説明していきます

#  Snapshotを初期化する

### ◯ プロジェクトのルートディレクトリで下記コマンドを実行する

```bash
$ fastlane snapshot init
```

`Root/fastlane/` 直下に下記が生成されます

- `Snapfile` ：snapshotの設定ファイル
- `SnapshotHelper.swift` ：UITestでsnapshotを生成するためのヘルパー関数群

`Root/` 直下に下記が生成されます

- `/screenshots` ：snapshotが保存されるディレクトリ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633746/af160c53-2305-824a-93a1-834319aa633e.png)


### ◯ SnapshotHelper.swiftを移動・ターゲットに追加

initでこのファイルを生成しただけではUITestで読み込めないので
ディレクトリを移動しつつ、UITestのターゲットに追加します
（移動せずそのままターゲットに追加でも大丈夫です）

最終的に `TERGETS` > `AppUITests` > `Build Phases` > `Compile Sources` に
`SnapshotHelper.swift` があればOKです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633746/7e3bff67-adfc-a2ea-b279-f959be8e8e38.png)

#  UITestを書く

スクリーンショットを自動で撮影するために、UITestをひと工夫します

### ◯ 全体像

```swift: AppUITest.swift
import XCTest

final class CounterUITests: XCTestCase {
    override func setUp() {
        super.setUp()

        continueAfterFailure = false
        let app = XCUIApplication()
        setupSnapshot(app)
        app.launch()
    }
    
    func test_sxample() {
        snapshot("LaunchScreen")
    }
}
```

### ◯ 詳細

setUpメソッドの中でsnapshotを取るための設定をします

`continueAffterFailure` はTestが失敗した時に実行を継続するかどうかを設定します
デフォルトは`true` です
Errorやテスト失敗時にそのまま動いてしまうので`false` に設定して
スクショを想定通りに撮れなかった時にDeliverをストップできるようにします

```swift: AppUITest.swift
continueAfterFailure = false
```

アプリケーションを初期化し

```swift: AppUITest.swift
let app = XCUIApplication()
```

`SnapshotHelper.swift` の`setupSnapshot`メソッドを使ってSnapshotをセットアップし

```swift
setupSnapshot(app)
```

appを起動します

```swift: AppUITest.swift
app.launch()
```

各テストでは`snapshot` メソッドを使ってスクショを撮影します

```swift: AppUITest.swift
snapshot("LaunchScreen")
```

#  Snapfileを編集する
下記のように編集します
```ruby: fastlane/Snapfile
# A list of devices you want to take the screenshots from
devices([
    "iPhone 8 Plus",
    "iPhone 13 Pro Max",
])

languages([
    "en-US",
    "ja",
])

# Automatically erase previously generated screenshots before taking a snapshot
clear_previous_screenshots(true)

# The name of the scheme which contains the UI Tests
scheme("Counter")

# Where should the resulting screenshots be stored?
output_directory("./fastlane/screenshots")
```

この後のステップで`fastlane snapshot run` を実行しますが
`output_directory("パス")`で指定した場所に`screenshots/`が生成されますが
後々 `fastlane Deliver` を使ってAppStoreにデリバーする際に
Sapshotで生成したスクショを読み込もうとするパスが 
`./fastlane/screenshots` なので
パスをここに指定しておくとあとあと楽です
#  Snapshotを単体実行する

```bash
$ fastlane snapshot run
```

指定した言語ごとにディレクトリが生成され
デバイスごとにスクリーンショットが保存されたらOKです！

htmlも生成してくれるのでそちらでも確認できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633746/4b51e4af-87fe-4d2b-e6fe-13faabd852a5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633746/3f1ab9c0-458d-713e-9ece-5a910c203045.png)



# Fastfileを編集してレーンを作る

下記レーンを追加します

```ruby:fastlane/Fastfile
desc "Take screenshots"
lane :screenshot do
    snapshot
end
```

下記コマンドでも実行できるようになります

```bash
$ fastlane screenshot
```

#  おわりに
これを使わずしてiOS開発は無理ですね！

他のfastlaneの機能も記事にしていこうと思います！