Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
DataStoreをテストする
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
mkeeda
April 04, 2025
Programming
620
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
DataStoreをテストする
Shibuya.apk #52の発表資料です
https://shibuya-apk.connpass.com/event/349013/
mkeeda
April 04, 2025
More Decks by mkeeda
See All by mkeeda
Google I/O 2026 個人的に気になりトピック
mkeeda
0
36
アジャイル & スクラム入門
mkeeda
0
260
そのAPI、誰のため? Androidライブラリ設計における利用者目線の実践テクニック
mkeeda
2
5.6k
Android StudioのAIコーディングツール、 ぶっちゃけどうなん???
mkeeda
0
680
時計仕掛けのCompose
mkeeda
1
590
What's new in Firebase for building gen AI features気になったところ
mkeeda
0
1k
手動DIの教訓
mkeeda
0
320
WebViewと向き合う
mkeeda
2
1.7k
お気に入りのAndroid Studio小技集
mkeeda
0
420
Other Decks in Programming
See All in Programming
Kiroで創り、AgentCoreで繋ぐ!AWSで実践する「AI-DLC」から「AIエージェント統合」までの最新地図
licux
4
690
DroidKaigi 2026 「個人開発という実験場: Android エンジニアが手にする4つの自由」
slashnephy
0
230
モジュールの視点からSwiftを読み解く #iosdc
s_shimotori
0
170
A2UI for Android: Safely Rendering AI-Generated UI with Jetpack Compose - DroidKaigi 2026
itsmedreamwalker
0
140
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
220
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
7
3k
Webの地図
yosuke_furukawa
PRO
6
4.5k
変化を抱擁するドキュメントの作り方 - ビジネスルール駆動開発がもたらす、コードとの新しい関係
ioki
2
210
新卒PdEのリアル
ryu1013
1
500
SREの越境 / SRE Collaboration
y0hgi
1
210
更なる可用性を求めて、5年間運用したKotlinのアプリケーションをGoでリプレイスする話
ken_tunc
0
260
Java 27新機能 / Java 27 new features
kishida
2
140
Featured
See All Featured
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
For a Future-Friendly Web
brad_frost
183
10k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
450
Designing for Performance
lara
611
70k
Unsuck your backbone
ammeep
672
58k
Amusing Abliteration
ianozsvald
1
300
Fireside Chat
paigeccino
43
4k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
5
660
Faster Mobile Websites
deanohume
310
32k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
74
42k
Abbi's Birthday
coloredviolet
4
10k
Transcript
DataStoreをテストする Shibuya.apk # 5 2 向井 田 一 平 (@mr_mkeeda)
• 向井 田 一 平 (むかいだ いっぺい) • 𝕏 :
@mr_mkeeda • Github: @mkeeda • Android Engineer at Cybozu, Inc • 最近ハマっているもの: ガンニバル🍖 2
DataStore “を” テストする • androidx.DataStore • DataStoreの処理 自 体をテストする •
ex. 独 自 実装のSerializerを使ったデータの読み書きをテスト • DataStoreを含めたテスト対象をテストする • ex. DataStoreをモックせずにRepositoryの実装をテスト 3
DataStoreテストの流れ 1 . DataStoreインスタンスを作成 • CoroutineDispatcherの差し替え ⭐ 2 . 前提の状況を作る
• 事前にデータを書き込んでおく • 別のテストケースで書き込んだデータの削除 ⭐ 3 . テストしたい処理を実 行 4 . 期待する振る舞いを検証 • データ書き込みしたファイルの中 身 を検証 ⭐ 4
CoroutineDispatcherの変え 方 5 val Context.testDataStore by dataStore( fileName = "test_file",
serializer = StringSerializer(defaultValue = "default"), scope = CoroutineScope(UnconfinedTestDispatcher() + Job()) // ⭐ ) // or val testDataStore = DataStoreFactory.create( serializer = StringSerializer(defaultValue = "default"), scope = CoroutineScope(UnconfinedTestDispatcher() + Job()), // ⭐ produceFile = { context.dataStoreFile(fileName = "test_file") } )
データの後始末 6 internal fun Context.clearDataStore() { File(filesDir, "/datastore").deleteRecursively() } @Before
fun setUp() { context.clearDataStore() } // or val testDataStore = DataStoreFactory.create( serializer = StringSerializer(defaultValue = "default"), produceFile = { /** Ұ࣌ϑΝΠϧΛ࡞Δ **/ } )
書き込まれたファイルの検証 方 法 7 val testDataStore = DataStoreFactory.create( serializer =
StringSerializer("default"), produceFile = { context.dataStoreFile(fileName = "test_file") } ) testDataStore.updateData { "Hello world" } // ⭐ val storedFile = context.filesDir.findFileBy("test_file") storedFile ?. readText() .shouldBe("Hello world") .shouldNotBe("default")
8 internal fun File.findFileBy(fileName: String): File? = searchFileRecursively(directory = this,
fileName) private fun searchFileRecursively( directory: File, fileName: String, ): File? { directory.listFiles() ?. forEach { file -> if (file.isDirectory) { searchFileRecursively(file, fileName) ?. let { return it } } else if (file.name.contains(fileName)) { return file } } return null }
ファイル参照の競合 • DataStoreインスタンスは シングルトンで使う設計 • 同 一 のファイル名を 同時に参照するとエラー •
AndroidTestだと1プロセス内で 同 一 参照があるとエラー • 複数のテストを実 行 しないと エラーに気付けない! 9 DataStore ファイル class TestA class TestB fun test 1 () fun test 2 () fun test 3 () ⚠ ⚠ ⚠
ファイル参照の競合を回避する • ファイル名をテストケース単位で ユニークにする • JUnitのRuleを作るといいかも (試してない) 1 0 DataStore
TestA_test 1 _ fi le class TestA class TestB fun test 1 () fun test 2 () fun test 3 () DataStore TestA_test 2 _ fi le DataStore TestB_test 3 _ fi le
ファイルの参照を解放させたい • DataStoreは稼働中、書き込み先のファイルを占有する • 2番 目 に参照してきたDataStoreはエラーになる • では、こういうのはどうやってテストする? 1
. DataStoreAでデータを書き込み 2 . アプリ再起動などでDataStoreAが破棄 3 . 1で書き込んだデータをDataStoreBで読み込める 1 1
1 2 val testDataStore1 = DataStoreFactory.create( produceFile = { context.dataStoreFile(fileName
= "test_file") } ) testDataStore1.updateData { "Hello world" } // ΞϓϦϓϩηεΛऴྃͤ͞Δ // ʁʁʁ⭐ val testDataStore2 = DataStoreFactory.create( produceFile = { context.dataStoreFile(fileName = "test_file") } ) // ॻ͖ࠐΜͩσʔλ͕ಡΈࠐΊΔ͜ͱΛ֬ೝ testDataStore2.data.first() shouldBe "Hello world"
Jobを完了させるとDataStoreはファイル参照を解放する 1 3 val dataStoreJob = Job() val testDataStore1 =
DataStoreFactory.create( scope = CoroutineScope( UnconfinedTestDispatcher() + dataStoreJob // ⭐ ), produceFile = { context.dataStoreFile(fileName = "test_file") } ) dataStoreJob.complete()
DataStoreテストまとめ • 基本編 • CoroutineDispatcherはscopeを差し替える • テスト後の後始末はファイルごと消す • DataStoreの書き込み挙動はファイルの中 身
を検証する • 上級編 • ファイル参照の競合に気をつける • DataStoreのファイル参照を解放するには scopeに含めたJobを完了させる 1 4
参考 • DataStore and testing | Android Developers | Medium
https://medium.com/androiddevelopers/datastore-and-testing- edf 7 ae 8 df 3 d 8 • androidx.DataStoreのテストコード https://cs.android.com/androidx/platform/frameworks/support/+/ androidx-main:datastore/ 1 5