$30 off During Our Annual Pro Sale. View Details »

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

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/

Sato Takeshi

December 18, 2020
Tweet

More Decks by Sato Takeshi

Other Decks in Technology

Transcript

  1. swift-snapshot-testingで
    Snapshot Testingを

    効率化

    merpay Tech Talk ~for iOS Engineers~

    2020 年 12 月 18 日 

    #merpay_techtalk


    View Slide

  2. Who am I

    ● Name

    ● 佐藤剛士(さとうたけし)

    ● Company

    ● Merpay, Inc.(2019/01 ~)

    ● Role

    ● Software Engineer (iOS)

    ● Account

    ● Twitter: @hatakenokakashi

    ● Facebook: 佐藤剛士

    ● GitHub: SatoTakeshiX


    View Slide

  3. 今日話すこと

    ● Snapshot Testingの位置づけ

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

    ● swift-snapshot-testingの紹介

    ● swift-snapshot-testingの苦手分野

    ● swift-snapshot-testingの導入方針

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

    ● 出力画像ガチャ問題

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


    View Slide

  4. Snapshot Testingの位置づけ

    種類 目的 実行時間
    Unit Test ロジックを担保する 小
    Snapshot Testing Viewの画像を出力しレイアウトを
    確認

    UI Test 実際のユーザーとほぼ同じ環境で
    アプリを動かし動作を確認

    View Slide

  5. メルペイが実施していた

    Snapshot Testing


    View Slide

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


    View Slide

  7. iOSSnapshotTestCase


    View Slide

  8. 使っていくうちにいくつか問題が出てきた





    ● 実行時間の増加

    ● 出力画像ガチャ問題


    View Slide

  9. 実行時間の増加

    ● iOSSnapshotTestCaseはキャプチャするViewサイズは自分で作らな
    いといけない

    ● UIScreen.main.boundsでWindowを作成し、そのWindowの
    rootViewControllerに対象のViewControllerを代入していた

    ● 複数端末をキャプチャするために、実行端末を増やしていた

    ● iPhone SE, 6s, 7, 8, Xs, Xr, X, 11 Pro, iPadの10種類

    ● そのため、実行時間が増えていた


    View Slide

  10. iOSSnapshotTestCaseのコード


    View Slide

  11. 実行時間の増加

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


    View Slide

  12. 出力画像ガチャ問題

    もともとの画像
 テストで出力された画像 


    View Slide

  13. 出力画像ガチャ問題

    もともとの画像
 テストで出力された画像 


    View Slide

  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のベンダーによって処理が異なる?

    ● 透過処理の画像を使うと時々差異が出てしまう


    View Slide

  15. swift-snapshot-testingの紹介


    View Slide

  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対応


    View Slide

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


    View Slide

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


    View Slide

  19. swift-snapshot-testing


    View Slide

  20. Dynamic Type テストコード


    View Slide

  21. Dynamic Type 出力画像


    View Slide

  22. swift-snapshot-testingの

    苦手分野


    View Slide

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

    ● window全体を撮るスナップショットが苦手

    ○ https://github.com/pointfreeco/swift-snapshot-testing/issues/279

    ● ポップアップやハーフモーダルの撮影が該当

    ● 自分でUIApplication.shared.windowsからwindowを作成


    View Slide

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


    View Slide

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

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


    View Slide

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

    ● iOSSnapshotTestCaseと併用して使用する

    ○ Window全体のスナップショットはiOSSnapshotTestCase

    ○ View自体のスナップショットはswift-snapshot-testing

    ● swift-snapshot-testing用のtargetを追加

    ○ iOSSnapshotTestCase用のtargetはすでに追加済み

    ● すでに実装したスナップショットテストは徐々に
    swift-snapshot-testingへ移行


    View Slide

  27. 実行端末を削減して

    実行時間を短縮


    View Slide

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

    ● swift-snapshot-testing導入後、2020年9月、10端末で実行していた
    Snapshot Testを1端末に削減

    ● 半分ほどにテスト時間を短縮


    View Slide

  29. swift-snapshot-testingの導入

    2020年9月のとあるworkflow結果 


    View Slide

  30. 出力画像ガチャ問題


    View Slide

  31. 出力画像ガチャ問題

    ● どうやっても解決できず

    ● iOSSnapshotTestCaseもswift-snapshot-testingも画像出力処理は
    同じ実装

    ● しきい値を下げることで解決

    ○ precisionプロパティ

    ● swift-snapshot-testingではrecursiveDescriptionでView階層をtext
    に出力できる

    ● recursiveDescriptionをもってレイアウト変更がないことの担保をする


    View Slide

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

    0.9を指定
    10%差異があっ
    ても許容する

    View Slide

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

    View階層を
    Textファイルに
    出力

    View Slide

  34. recursiveDescription textファイル


    View Slide

  35. recursiveDescriptionの注意点

    ● 実行端末によってレンダリング結果が異なる

    ○ 解像度、スクリーンサイズなどが影響

    ● 実行端末を限定する必要がある


    View Slide

  36. Snapshot Testingを

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


    View Slide

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


    View Slide

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


    View Slide

  39. まだ少し面倒?


    View Slide


  40. Xcode Previews
 swift-snapshot-testing 


    View Slide

  41. まとめ

    ● メルペイのスナップショットテストでは複数端末での実行時間と画像
    出力が異なる問題があった

    ● swift-snapshot-testingを導入した

    ● 一度の実行で複数端末のキャプチャを撮影できるようになった

    ● 画像出力異なる問題は目視&View階層のText出力で担保

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


    View Slide