Upgrade to Pro — share decks privately, control downloads, hide ads and more …

swift-snapshot-testingでVisual Testingを効率化

53e2d354b3299d64a54af680865516d5?s=47 Sato Takeshi
December 18, 2020

swift-snapshot-testingでVisual Testingを効率化

merpay Tech Talk ~for iOS Engineers~
https://mercari.connpass.com/event/197804/

参考
メルペイ iOS にスナップショットテストを導入した話https://engineering.mercari.com/blog/entry/ios-snapshot-test-case/

53e2d354b3299d64a54af680865516d5?s=128

Sato Takeshi

December 18, 2020
Tweet

Transcript

  1. swift-snapshot-testingで Snapshot Testingを
 効率化
 merpay Tech Talk ~for iOS Engineers~


    2020 年 12 月 18 日 
 #merpay_techtalk

  2. Who am I
 • Name
 • 佐藤剛士(さとうたけし)
 • Company
 •

    Merpay, Inc.(2019/01 ~)
 • Role
 • Software Engineer (iOS)
 • Account
 • Twitter: @hatakenokakashi
 • Facebook: 佐藤剛士
 • GitHub: SatoTakeshiX

  3. 今日話すこと
 • Snapshot Testingの位置づけ
 • メルペイが実施していたSnapshot Testing
 • swift-snapshot-testingの紹介
 •

    swift-snapshot-testingの苦手分野
 • swift-snapshot-testingの導入方針
 • 実行端末を削減して実行時間を短縮
 • 出力画像ガチャ問題
 • Snapshot Testingを開発フローに導入しやすくする

  4. Snapshot Testingの位置づけ
 種類 目的 実行時間 Unit Test ロジックを担保する 小 Snapshot

    Testing Viewの画像を出力しレイアウトを 確認 中 UI Test 実際のユーザーとほぼ同じ環境で アプリを動かし動作を確認 大
  5. メルペイが実施していた
 Snapshot Testing


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


  7. iOSSnapshotTestCase


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


  9. 実行時間の増加
 • iOSSnapshotTestCaseはキャプチャするViewサイズは自分で作らな いといけない
 • UIScreen.main.boundsでWindowを作成し、そのWindowの rootViewControllerに対象のViewControllerを代入していた
 • 複数端末をキャプチャするために、実行端末を増やしていた
 •

    iPhone SE, 6s, 7, 8, Xs, Xr, X, 11 Pro, iPadの10種類
 • そのため、実行時間が増えていた

  10. iOSSnapshotTestCaseのコード


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


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


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


  14. 公式の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のベンダーによって処理が異なる?
 • 透過処理の画像を使うと時々差異が出てしまう

  15. swift-snapshot-testingの紹介


  16. swift-snapshot-testingとは?
 • Swiftと関数型言語を解説するWebマガジンPoint-Freeが運営
 • Swiftで実装
 • 各端末の画面サイズのプリセットあり
 ◦ iPhoneSE, 8,

    8 Plus, X, XsMax, Xr, iPadMini など
 ◦ iPadは縦向き、横向きを指定可能
 • 画像だけでなく、View階層をtextファイルに出力も可能
 • Dynamic TypeのSnapshot Testにも対応
 • SwiftUI対応

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


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


  19. swift-snapshot-testing


  20. Dynamic Type テストコード


  21. Dynamic Type 出力画像


  22. swift-snapshot-testingの
 苦手分野


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


  24. swift-snapshot-testingの導入方針


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


  26. swift-snapshot-testingの導入方針
 • iOSSnapshotTestCaseと併用して使用する
 ◦ Window全体のスナップショットはiOSSnapshotTestCase
 ◦ View自体のスナップショットはswift-snapshot-testing
 • swift-snapshot-testing用のtargetを追加
 ◦

    iOSSnapshotTestCase用のtargetはすでに追加済み
 • すでに実装したスナップショットテストは徐々に swift-snapshot-testingへ移行

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


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


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


  30. 出力画像ガチャ問題


  31. 出力画像ガチャ問題
 • どうやっても解決できず
 • iOSSnapshotTestCaseもswift-snapshot-testingも画像出力処理は 同じ実装
 • しきい値を下げることで解決
 ◦ precisionプロパティ


    • swift-snapshot-testingではrecursiveDescriptionでView階層をtext に出力できる
 • recursiveDescriptionをもってレイアウト変更がないことの担保をする

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

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

  34. recursiveDescription textファイル


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


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


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


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


  39. まだ少し面倒?


  40. Xcode Previews
 swift-snapshot-testing 


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


    • テンプレート作成でSnapshot Testingをやりやすくする