Slide 1

Slide 1 text

swift-snapshot-testingで Snapshot Testingを
 効率化
 merpay Tech Talk ~for iOS Engineers~
 2020 年 12 月 18 日 
 #merpay_techtalk


Slide 2

Slide 2 text

Who am I
 ● Name
 ● 佐藤剛士(さとうたけし)
 ● Company
 ● Merpay, Inc.(2019/01 ~)
 ● Role
 ● Software Engineer (iOS)
 ● Account
 ● Twitter: @hatakenokakashi
 ● Facebook: 佐藤剛士
 ● GitHub: SatoTakeshiX


Slide 3

Slide 3 text

今日話すこと
 ● Snapshot Testingの位置づけ
 ● メルペイが実施していたSnapshot Testing
 ● swift-snapshot-testingの紹介
 ● swift-snapshot-testingの苦手分野
 ● swift-snapshot-testingの導入方針
 ● 実行端末を削減して実行時間を短縮
 ● 出力画像ガチャ問題
 ● Snapshot Testingを開発フローに導入しやすくする


Slide 4

Slide 4 text

Snapshot Testingの位置づけ
 種類 目的 実行時間 Unit Test ロジックを担保する 小 Snapshot Testing Viewの画像を出力しレイアウトを 確認 中 UI Test 実際のユーザーとほぼ同じ環境で アプリを動かし動作を確認 大

Slide 5

Slide 5 text

メルペイが実施していた
 Snapshot Testing


Slide 6

Slide 6 text

https://engineering.mercari.com/blog/entry/ios-snapshot-test-case/ 


Slide 7

Slide 7 text

iOSSnapshotTestCase


Slide 8

Slide 8 text

使っていくうちにいくつか問題が出てきた
 
 
 
 
 ● 実行時間の増加
 ● 出力画像ガチャ問題


Slide 9

Slide 9 text

実行時間の増加
 ● iOSSnapshotTestCaseはキャプチャするViewサイズは自分で作らな いといけない
 ● UIScreen.main.boundsでWindowを作成し、そのWindowの rootViewControllerに対象のViewControllerを代入していた
 ● 複数端末をキャプチャするために、実行端末を増やしていた
 ● iPhone SE, 6s, 7, 8, Xs, Xr, X, 11 Pro, iPadの10種類
 ● そのため、実行時間が増えていた


Slide 10

Slide 10 text

iOSSnapshotTestCaseのコード


Slide 11

Slide 11 text

実行時間の増加
 Unit Testよりもsnapshot testのほうが時間がかかっている


Slide 12

Slide 12 text

出力画像ガチャ問題
 もともとの画像
 テストで出力された画像 


Slide 13

Slide 13 text

出力画像ガチャ問題
 もともとの画像
 テストで出力された画像 


Slide 14

Slide 14 text

公式のIssue
 ● Test results depends on Mac device #109
 ○ 2019年10月投稿
 ○ https://github.com/uber/ios-snapshot-test-case/issues/109
 ● Catalinaにバージョンアップしたときから画像の差異が出るように なった
 ● Xcode 11からシュミレーターのプロセスにGPUが使われるようになっ たそう
 ○ GPUのベンダーによって処理が異なる?
 ● 透過処理の画像を使うと時々差異が出てしまう


Slide 15

Slide 15 text

swift-snapshot-testingの紹介


Slide 16

Slide 16 text

swift-snapshot-testingとは?
 ● Swiftと関数型言語を解説するWebマガジンPoint-Freeが運営
 ● Swiftで実装
 ● 各端末の画面サイズのプリセットあり
 ○ iPhoneSE, 8, 8 Plus, X, XsMax, Xr, iPadMini など
 ○ iPadは縦向き、横向きを指定可能
 ● 画像だけでなく、View階層をtextファイルに出力も可能
 ● Dynamic TypeのSnapshot Testにも対応
 ● SwiftUI対応


Slide 17

Slide 17 text

swift-snapshot-testingのテストコード


Slide 18

Slide 18 text

swift-snapshot-testingのテストコード


Slide 19

Slide 19 text

swift-snapshot-testing


Slide 20

Slide 20 text

Dynamic Type テストコード


Slide 21

Slide 21 text

Dynamic Type 出力画像


Slide 22

Slide 22 text

swift-snapshot-testingの
 苦手分野


Slide 23

Slide 23 text

swift-snapshot-testingの苦手分野
 ● window全体を撮るスナップショットが苦手
 ○ https://github.com/pointfreeco/swift-snapshot-testing/issues/279
 ● ポップアップやハーフモーダルの撮影が該当
 ● 自分でUIApplication.shared.windowsからwindowを作成


Slide 24

Slide 24 text

swift-snapshot-testingの導入方針


Slide 25

Slide 25 text

swift-snapshot-testingの導入方針
 ● メルペイではポップアップやハーフモーダルなどのWindow全体を撮 影する画面が多くある


Slide 26

Slide 26 text

swift-snapshot-testingの導入方針
 ● iOSSnapshotTestCaseと併用して使用する
 ○ Window全体のスナップショットはiOSSnapshotTestCase
 ○ View自体のスナップショットはswift-snapshot-testing
 ● swift-snapshot-testing用のtargetを追加
 ○ iOSSnapshotTestCase用のtargetはすでに追加済み
 ● すでに実装したスナップショットテストは徐々に swift-snapshot-testingへ移行


Slide 27

Slide 27 text

実行端末を削減して
 実行時間を短縮


Slide 28

Slide 28 text

実行端末を削減して実行時間を短縮
 ● swift-snapshot-testing導入後、2020年9月、10端末で実行していた Snapshot Testを1端末に削減
 ● 半分ほどにテスト時間を短縮


Slide 29

Slide 29 text

swift-snapshot-testingの導入
 2020年9月のとあるworkflow結果 


Slide 30

Slide 30 text

出力画像ガチャ問題


Slide 31

Slide 31 text

出力画像ガチャ問題
 ● どうやっても解決できず
 ● iOSSnapshotTestCaseもswift-snapshot-testingも画像出力処理は 同じ実装
 ● しきい値を下げることで解決
 ○ precisionプロパティ
 ● swift-snapshot-testingではrecursiveDescriptionでView階層をtext に出力できる
 ● recursiveDescriptionをもってレイアウト変更がないことの担保をする


Slide 32

Slide 32 text

swift-snapshot-testingのテストコード
 0.9を指定 10%差異があっ ても許容する

Slide 33

Slide 33 text

swift-snapshot-testingのテストコード
 View階層を Textファイルに 出力

Slide 34

Slide 34 text

recursiveDescription textファイル


Slide 35

Slide 35 text

recursiveDescriptionの注意点
 ● 実行端末によってレンダリング結果が異なる
 ○ 解像度、スクリーンサイズなどが影響
 ● 実行端末を限定する必要がある


Slide 36

Slide 36 text

Snapshot Testingを
 開発フローに導入しやすくする


Slide 37

Slide 37 text

テンプレートファイルを用意する


Slide 38

Slide 38 text

ViewControllerを作ればすぐに作成できる


Slide 39

Slide 39 text

まだ少し面倒?


Slide 40

Slide 40 text

Xcode Previews
 swift-snapshot-testing 


Slide 41

Slide 41 text

まとめ
 ● メルペイのスナップショットテストでは複数端末での実行時間と画像 出力が異なる問題があった
 ● swift-snapshot-testingを導入した
 ● 一度の実行で複数端末のキャプチャを撮影できるようになった
 ● 画像出力異なる問題は目視&View階層のText出力で担保
 ● テンプレート作成でSnapshot Testingをやりやすくする