$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
20251203_AIxIoTビジネス共創ラボ_第4回勉強会_BP山崎.pdf
iotcomjpadmin
0
130
LayerX QA Night#1
koyaman2
0
250
子育てで想像してなかった「見えないダメージ」 / Unforeseen "hidden burdens" of raising children.
pauli
2
320
モダンデータスタックの理想と現実の間で~1.3億人Vポイントデータ基盤の現在地とこれから~
taromatsui_cccmkhd
2
260
たまに起きる外部サービスの障害に備えたり備えなかったりする話
egmc
0
400
『君の名は』と聞く君の名は。 / Your name, you who asks for mine.
nttcom
1
110
2025年 開発生産「可能」性向上報告 サイロ解消からチームが能動性を獲得するまで/ 20251216 Naoki Takahashi
shift_evolve
PRO
2
220
1人1サービス開発しているチームでのClaudeCodeの使い方
noayaoshiro
2
570
フィッシュボウルのやり方 / How to do a fishbowl
pauli
2
370
アプリにAIを正しく組み込むための アーキテクチャ── 国産LLMの現実と実践
kohju
0
200
「もしもデータ基盤開発で『強くてニューゲーム』ができたなら今の僕はどんなデータ基盤を作っただろう」
aeonpeople
0
230
Bedrock AgentCore Memoryの新機能 (Episode) を試してみた / try Bedrock AgentCore Memory Episodic functionarity
hoshi7_n
2
1.7k
Featured
See All Featured
Everyday Curiosity
cassininazir
0
110
Navigating Team Friction
lara
191
16k
The World Runs on Bad Software
bkeepers
PRO
72
12k
BBQ
matthewcrist
89
9.9k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
0
75
Reality Check: Gamification 10 Years Later
codingconduct
0
1.9k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Leo the Paperboy
mayatellez
0
1.2k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
290
The browser strikes back
jonoalderson
0
120
Designing for Timeless Needs
cassininazir
0
92
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.2k
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/