$30 off During Our Annual Pro Sale. View Details »
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
What is iOSSnapshotTestCase
Search
Shingo Tamaki
August 24, 2018
Technology
1
960
What is iOSSnapshotTestCase
Description of how to use iOSSnapshotTestCase.
Shingo Tamaki
August 24, 2018
Tweet
Share
More Decks by Shingo Tamaki
See All by Shingo Tamaki
Use Gemini CLI from Claude Code as part of Sub Agent
tamaki
0
240
Let's make an Immersive Video with APMP
tamaki
0
37
Firebase Studioで始めるモバイルアプリ開発入門
tamaki
0
28
Introduction to Claude Code Action
tamaki
0
730
AIエージェントを使ったiOSアプリ開発を試してみた
tamaki
0
160
沖縄モバイルアプリ開発勉強会#1
tamaki
0
130
iOSアプリ開発を始めよう
tamaki
0
220
詳解xcresult.pdf
tamaki
0
410
メルペイでのリグレッションテスト自動化推進のこれまでとこれから
tamaki
0
800
Other Decks in Technology
See All in Technology
【開発を止めるな】機能追加と並行して進めるアーキテクチャ改善/Keep Shipping: Architecture Improvements Without Pausing Dev
bitkey
PRO
1
130
AgentCoreとStrandsで社内d払いナレッジボットを作った話
motojimayu
1
940
20251219 OpenIDファウンデーション・ジャパン紹介 / OpenID Foundation Japan Intro
oidfj
0
500
[2025-12-12]あの日僕が見た胡蝶の夢 〜人の夢は終わらねェ AIによるパフォーマンスチューニングのすゝめ〜
tosite
0
180
投資戦略を量産せよ 2 - マケデコセミナー(2025/12/26)
gamella
0
390
TED_modeki_共創ラボ_20251203.pdf
iotcomjpadmin
0
150
まだ間に合う! Agentic AI on AWSの現在地をやさしく一挙おさらい
minorun365
17
2.7k
Amazon Quick Suite で始める手軽な AI エージェント
shimy
1
1.9k
AWSに革命を起こすかもしれない新サービス・アップデートについてのお話
yama3133
0
500
NIKKEI Tech Talk #41: セキュア・バイ・デザインからクラウド管理を考える
sekido
PRO
0
210
20251218_AIを活用した開発生産性向上の全社的な取り組みの進め方について / How to proceed with company-wide initiatives to improve development productivity using AI
yayoi_dd
0
660
通勤手当申請チェックエージェント開発のリアル
whisaiyo
3
460
Featured
See All Featured
Building Adaptive Systems
keathley
44
2.9k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
196
70k
Are puppies a ranking factor?
jonoalderson
0
2.4k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
130
Art, The Web, and Tiny UX
lynnandtonic
304
21k
What does AI have to do with Human Rights?
axbom
PRO
0
1.9k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
2
260
The Curse of the Amulet
leimatthew05
0
4.7k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
359
30k
How to Ace a Technical Interview
jacobian
281
24k
Navigating Team Friction
lara
191
16k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
120
Transcript
iOSSnapshotTestCase ͰϏϡʔͷςετΛߦ͏
ࣗݾհ • ۄ৴ޛ • iOS Engineer • iOSDC2018Ͱελοϑ͠·͢
iOSSnapshotTestCaseͱ View based testingΛߦ͏ͨΊͷπʔϧ ݩFBSnapshotTestCaseͰɺͱͱFacebook Ϗϡʔͷը૾Λ͖߹ΘͤͯมߋҰக͢Δ͔Λςετ͢Δػೳ ͕͋Γ·͢ɻ
ḪΔࣄҰલ
ḪΔࣄҰલ
ผͷखஈΛݕ౼ͯ͠ΈͨΓ WiremockΛͬͨUIςετ https://speakerdeck.com/tamaki/wiremockdexing-uuitesuto
σϝϦοτ͋Γ·ͨ͠ • XCUITestͷ࣮ߦ࣌ؒ • XCUITestͰը໘ͷঢ়ଶΛ࡞Δखؒ
ͱࢥͬͨΒ...
iOSSnapshotTestCaseͱͯ͠෮׆ Uber͕Ҿ͖ܧ͙ܗͰ෮׆ https://github.com/uber/ios-snapshot-test-case
࠶ͼ͍࢝ΊΔࣄʹ͠·ͨ͠ɻ
iOSSnapshotTestCase ͷ͍ํ
Πϯετʔϧ target "Tests" do use_frameworks! pod 'iOSSnapshotTestCase' end
ઃఆ • FBREFERENCEIMAGEDIR: $(SOURCEROOT)/$ (PROJECT_NAME)Tests/ReferenceImages • IMAGEDIFFDIR: $(SOURCEROOT)/$(PROJECTNAME)Tests/ FailureDiffs
ςετ࡞ FBSnapshotTestCaseΛܧঝͨ͠ςετέʔεΛ࡞͠·͢ɻ class iOSSnapshotTestCaseSampleTests: FBSnapshotTestCase { }
ςετϝιου࡞ FBSnapshotVerifyViewͰରͷϏϡʔΛνΣοΫ͠·͢ɻ ରͷϏϡʔͷαΠζCGRect(x:y:width:height)ͳͲͰࢦఆ͠ ͓͖ͯ·͠ΐ͏ɻ view.frame = CGRect(x: 0, y: 0,
width: 768, height: 1024) FBSnapshotVerifyView(view, identifier: "view id")
ϦϑΝϨϯεը૾ͷ࡞ recordMode͕trueͷͰςετΛ࣮ߦ͢ΔͱϦϑΝϨϯε༻ը૾ ͕ੜ͞Ε·͢ɻ override func setUp() { super.setUp() recordMode =
true }
ϦϑΝϨϯεը૾ ReferenceImages_64ͷԼʹςετλʔήοτ໊.ςετέʔ ε໊ͷσΟϨΫτϦͱɺ ͦͷԼʹ͖߹ΘͤʹඞཁͱͳΔࢀর༻ը૾͕࡞͞Ε·͢ɻ iOSSnapshotTestCaseSampleTests/ ├── Info.plist ├── ReferenceImages_64 │
└── iOSSnapshotTestCaseSampleTests.TopScreenSnapshotTests │ └──
[email protected]
└── TopScreenSnapshotTests.swift
ϦϑΝϨϯεը૾
ςετͷ࣮ߦ recordModeΛfalseʹ͢ΔࣄΛΕͳ͍Α͏ʹɻ override func setUp() { super.setUp() recordMode = false
}
ςετ݁Ռ
ը໘͕มߋ͠ςετΛ࣮ߦ͢Δͱ... ૂ͍௨Γςετࣦഊ͠·ͨ͠Ͷʁ
FailureDiffsΛݟͯΈΑ͏ ├── FailureDiffs │ └── iOSSnapshotTestCaseSampleTests.TopScreenSnapshotTests │ ├──
[email protected]
│
├──
[email protected]
│ └──
[email protected]
├── Info.plist ├── ReferenceImages_64 │ └── iOSSnapshotTestCaseSampleTests.TopScreenSnapshotTests │ └──
[email protected]
└── TopScreenSnapshotTests.swift
FailureDiffsͷத FailureDiffsσΟϨΫτϦ͕ੜ͞Εɺ3ͭͷϑΝΠϧ͕ೖͬͯ· ͢ file name description diff_*.png Ϗϡʔͷ͖߹Θͤࠩ failed_*.png ݱࡏͷϏϡʔ
reference_*.png ࢀর༻ͷϏϡʔ(͋Δ͖Ϗϡʔͷը૾)
FailureDiffsͷத
ࢀর༻ͷը૾ͷ࠶ੜ ઌ΄ͲͷςετϏϡʔʹ͕ࠩ͋Γςετࣦഊ͠·ͨ͠ ͕ɺఆͨ͠௨Γͳ༁Ͱ͔͢Βɺ࠶ࢀর༻ͷը૾Λొ͠ ͠·͢ɻ
جຊతͳ͍ํ(·ͱΊ) ͜ͷΑ͏ͳ࡞ۀΛ܁Γฦ͢ࣄͰҎԼͷΑ͏ͳԸܙΛड͚Δ͜ͱ ͕Ͱ͖·͢ɻ • ҙਤ͠ͳ͍ը໘่ΕΛݕग़དྷΔ • PR࣌ʹϦϑΝϨϯεը૾ؚ͕·ΕΔࣄͰը໘ͷ֬ೝָ͕ʹͳ Δ
Tips
ෳαΠζͷରԠ ϏϡʔͷαΠζॎԣͷରԠͳͲͨ͘͠ͳΓ·͢ΑͶʁ ྫ͑ྻڍܕͰσόΠεαΠζΛఆٛ enum DeviceSize: String { case size_10_5_inch =
"10.5inch" case size_12_9_inch = "12.9inch" static func all() -> [DeviceSize] { return [ .size_10_5_inch, .size_12_9_inch, ] }
ෳαΠζͷରԠ ͖ຖͷ֤σόΠεͷαΠζ(Rect)Λฦ͢ϝιουΛੜͨ͠Γ ͢ΔͱָʹͳΓͦ͏Ͱ͢ɻ func frame(with orientation: UIInterfaceOrientation) -> CGRect {
switch (self, orientation) { case (.size_10_5_inch, .portrait): return CGRect(x: 0, y: 0, width: 834, height: 1112) case (.size_10_5_inch, .landscapeLeft): return CGRect(x: 0, y: 0, width: 1112, height: 834) case (.size_12_9_inch, .portrait): return CGRect(x: 0, y: 0, width: 1024, height: 1366) case (.size_12_9_inch, .landscapeLeft): return CGRect(x: 0, y: 0, width: 1366, height: 1024) default: return CGRect.zero } } }
ෳαΠζͷରԠ FBSnapshotVerifyViewجຊతʹ1ϏϡʔͣͭVerify͍ͯ͘͠ͷ Ͱ͕͢ɺSnapshotVerifyViewAllSizeΛ࡞ͬͯෳαΠζΛҰ ؾʹςετग़དྷΔΑ͏ʹͨ͠Γ͍ͯ͠·͢ɻ extension FBSnapshotTestCase { public func SnapshotVerifyViewAllSize(_
vc: UIViewController, identifier: String = "", orientation: UIInterfaceOrientation) { for size in DeviceSize.all() { XCTContext.runActivity(named: "\(identifier)_\(size.rawValue)", block: { activity in let view = vc.view! view.frame = size.frame(with: orientation) FBSnapshotVerifyView(view, identifier: activity.name) }) } } }
Ϗϡʔͷঢ়ଶ࡞Γʹ͍ͭͯ • XCUIDevice.shared.orientationΛsetupͰ੍ޚग़དྷΔʁ • ࣦഊ͢Δ͜ͱ͕͋ͬͨ(or ग़དྷͳ͔ͬͨ) هԱʹͳ ͍ •
࣮ߦΓ͘ͳͬͨ • UIςετͷΈΛ͏ࣄʹҧײΛײͨ͡ • ૉʹΠχγϟϥΠβͰDI͢Δࣄʹͨ͠
ɹϨϏϡʔ࣌ʹཱͭ GithubGitlabը૾ࠩΛදࣔͰ͖ΔΑ͏ʹͳͬͨͷͰϨ Ϗϡʔ࣌ʹԿ͕มΘ͔ͬͨΛ֬ೝ͍͢͠
ݒ೦ • ը໘͕ଟ͍ΞϓϦͷ߹ͷϦϙδτϦͷαΠζ૿Ճ • Uber͕ϝϯςΊΔ • ࠓࣗͰר͖औͬͯϝϯς͢Δؾ࣋ͪΛ࣋ͱ͏͔ͳ ͱɻ
·ͱΊ • UIςετE2EͰͳ͘ϏϡʔͷΈΛςετ͍ͨ͠߹ʹ͓ ͢͢ΊͰ͢ • ௨ৗͷ୯ମςετΑΓ͔͔࣌ؒΓ·͢ • ϏϡʔͷϓϩύςΟͳͲʹΞΫηεͯ͠ςετ͢Δํ๏ ͋Δ
Ҏ্ɺ͝੩ௌ͋Γ͕ͱ͏ ͍͟͝·ͨ͠ɻ
ࢀߟ https://github.com/facebookarchive/ios-snapshot-test-case https://github.com/facebookarchive/ios-snapshot-test-case/ issues/227#issuecomment-335175385 https://www.objc.io/issues/15-testing/snapshot-testing/