Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Swiftの “private” を テストする / Testing Swift "private"
Search
Yutaro Muta
February 18, 2025
Technology
0
230
Swiftの “private” を テストする / Testing Swift "private"
Mobile Act OSAKA 15
https://mobileact.connpass.com/event/343364/
Yutaro Muta
February 18, 2025
Tweet
Share
More Decks by Yutaro Muta
See All by Yutaro Muta
猫と暮らす Google Nest Cam生活🐈 / WebRTC with Google Nest Cam
yutailang0119
0
200
Apple Vision Pro購入RTA 1泊3日弾丸ハワイツアー / RTA: Purchase Apple Vision Pro in Hawaii
yutailang0119
0
1.4k
個人開発のたのしみ / Enjoying personal development
yutailang0119
0
1k
バックポートして学ぶ新APIの仕組み
yutailang0119
0
2.9k
Backport AsyncImage
yutailang0119
0
730
xcrun Essentials
yutailang0119
6
1.3k
Let's Coding SwiftUI on iPad!
yutailang0119
1
520
Property Wrapperで遊ぼう / Play with Property Wrapper
yutailang0119
2
330
Back of First Screen AB test of Hatena Bookmark iOS app with Firebase AB Testing
yutailang0119
0
320
Other Decks in Technology
See All in Technology
Claude Codeは仕様駆動の夢を見ない
gotalab555
23
6.4k
Claude CodeでKiroの仕様駆動開発を実現させるには...
gotalab555
3
1k
ロールが細分化された組織でSREと協働するインフラエンジニアは何をするか? / SRE Lounge #18
kossykinto
0
210
Serverless Meetup #21
yoshidashingo
1
120
Backlog AI アシスタントが切り開く未来
vvatanabe
1
130
Segment Anything Modelの最新動向:SAM2とその発展系
tenten0727
0
720
九州の人に知ってもらいたいGISスポット / gis spot in kyushu 2025
sakaik
0
140
【新卒研修資料】数理最適化 / Mathematical Optimization
brainpadpr
26
13k
o11yツールを乗り換えた話
tak0x00
2
930
마라톤 끝의 단거리 스퍼트: 2025년의 AI
inureyes
PRO
1
740
LLMで構造化出力の成功率をグンと上げる方法
keisuketakiguchi
0
770
Vision Language Modelと自動運転AIの最前線_20250730
yuyamaguchi
4
1.3k
Featured
See All Featured
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
BBQ
matthewcrist
89
9.8k
Visualization
eitanlees
146
16k
Building an army of robots
kneath
306
45k
How to train your dragon (web standard)
notwaldorf
96
6.2k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
8
440
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.6k
Bash Introduction
62gerente
614
210k
Thoughts on Productivity
jonyablonski
69
4.8k
Making the Leap to Tech Lead
cromwellryan
134
9.5k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
The Invisible Side of Design
smashingmag
301
51k
Transcript
Swiftの “private” を テストする id:yutailang0119 / @yutailang0119 Mobile Act OSAKA
15 1
Who am I!? • id:yutailang0119 ◦ @yutailang0119 • 株式会社はてな ◦
@京都オフィス ◦ アプリケーションエンジニア ▪ iOS/Android ◦ サービスプラットフォームチーム • try! Swift Tokyo Organizer • AVP座談会 🥽 2
3 Introduction
Introduction • private/fileprivateは、参照範囲を制限 ◦ @testableもアクセスできない ◦ open, package, internalはアクセス可能 •
Javaには @VisibleForTesting がある ◦ https://developer.android.com/reference/androidx/annotation/VisibleForTesting 4
Access Level 5 • open • package • internal •
fileprivate • private https://docs.swift.org/swift-book/documentation/the-swift-programming-language/accesscontrol/
6 Motivation
Motivation • テストのためのinternalを避けたい ◦ e.g.) 🙅 コメントでの規制 VisibleForTesting • アクセスのバイパス手段がほしい
7
8 Proposed solution
9 yutailang0119/swift-bypass-accessing
yutailang0119/swift-bypass-accessing • Swift Macros ◦ @BypassAccess • ___ prefix付きコード生成 PeerMacro
• #if DEBUG & internal 10
PeerMacro @attached(peer, names: prefixed(___), named(___init)) public macro BypassAccess() = #externalMacro(
module: "BypassAccessingMacros", type: "BypassAccessMacro" ) 11
12 Detailed design
Detailed design import BypassAccessing struct Declaration { @BypassAccess private let
property: String = "property" @BypassAccess fileprivate func function() -> String { #function } } 13
Detailed design import Testing import BypassAccessing @testable import Example struct
Tests { @Test func test() { let declaration = Declaration() #if DEBUG #expect(declaration.___property == "property") #expect(declaration.___function() == "function()") #endif } } 14
15 Macro
Macro import BypassAccessing struct Declaration { @BypassAccess private let property:
String = "property" } 16
Expand Macro import BypassAccessing struct Declaration { @BypassAccess private let
property: String = "property" #if DEBUG var ___property: String { property } #endif } 17
Macro import BypassAccessing struct Declaration { @BypassAccess fileprivate func function()
-> String { #function } } 18
Expand Macro import BypassAccessing struct Declaration { @BypassAccess fileprivate func
function() -> String { #function } #if DEBUG func ___function() -> String { function() } #endif } 19
20 Support Grammar
Support Grammar • let • var ◦ Stored ◦ Computed
• func • init 21
Modifier, Accessor • async, @MainActor • throws • static, class
• inout • Generics 22 https://docs.swift.org/swift-book/documentation/the-swift-programming-language/summaryofthegrammar
Modifier, Accessor 23 import BypassAccessing struct Declaration<Element> { @BypassAccess @MainActor
private init(_ arg: inout String) async throws where Element: Equatable {} #if DEBUG @MainActor static func ___init(_ arg: inout String) async throws -> Self where Element: Equatable { try await Self.init(_: &arg) } #endif }
Limitation • ❌ privateが現れるインターフェース ◦ Method must be declared private
because its parameter uses a private type • ❌ 型推論を伴うプロパティ ◦ ◦ '@BypassAccess' attribute require TypeAnnotation 24 @BypassAccess private var value = "value"
Support Grammar • 想定利用ケースは、テストを参照 ◦ https://github.com/yutailang0119/swift-bypass-accessing/tree/main/Tests/BypassAccessingTests • 考慮外パターンが存在しそう🫥 25
小噺 • SwiftSyntaxBuilder ◦ 複雑だが、今回のケースでは便利 ▪ 条件に応じて、Expressionを組み合わせ可能 ◦ PlainTextで実装後、SyntaxBuilderで書き直した •
Macroのテストは swift-testing が使えない ◦ XCTest ◦ https://github.com/swiftlang/swift-syntax/issues/2720 26
27 Conclusion
Conclusion • yutailang0119/swift-bypass-accessing ◦ @BypassAccess • 想定外を見つけたら、ご連絡ください📲 28
29 Advertisement
30
try! Swift Tokyo 2025 • 2025/04/09 - 11 • 立川ステージガーデン
• https://tryswift.jp/ 31
hatena.co.jp/recruit 32 32