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
マルチモジュールなプロジェクトでテストはどう変わるか? / How change testin...
Search
tkmnzm
February 07, 2019
Programming
13
22k
マルチモジュールなプロジェクトでテストはどう変わるか? / How change testing in modular architecture
tkmnzm
February 07, 2019
Tweet
Share
More Decks by tkmnzm
See All by tkmnzm
AndroidアプリのUIバリエーションをあの手この手で確認する / Check UI variations of Android apps by various means
tkmnzm
1
1.4k
Androidアプリの良いユニットテストを考える / Thinking about good unit tests for Android apps
tkmnzm
5
9k
Google I:O 2023 Androidの自動テストアップデートまとめ / Google I:O 2023 Android Testing Update Recap
tkmnzm
0
640
コルーチンのエラーをテストするためのTips / Tips for testing Kotlin Coroutine errors
tkmnzm
0
1.2k
Androidのモダンな技術選択にあわせて自動テストも アップデートしよう / Update your automated tests to match Android's modern technology choices
tkmnzm
3
2.4k
SWET dev-vitalチームによるプロジェクトの健康状態可視化の取り組み / SWET dev-vital team's efforts to visualize the health of the project
tkmnzm
1
1.3k
モバイルアプリテスト入門 / Getting Started with Mobile App Testing
tkmnzm
1
580
25分で作るAndroid Lint / Android Lint made in 25 minutes
tkmnzm
0
960
2年半ぶりのプロダクト開発であらためて感じた自動テストの大切さ / realized the importance of automatic testing with product development for the first time in two and a half years
tkmnzm
1
820
Other Decks in Programming
See All in Programming
スキーマ駆動で、Zod OpenAPI Honoによる、API開発するために、Hono Takibiというライブラリを作っている
nakita628
0
330
Things You Thought You Didn’t Need To Care About That Have a Big Impact On Your Job
hollycummins
0
260
kiroとCodexで最高のSpec駆動開発を!!数時間で web3ネイティブなミニゲームを作ってみたよ!
mashharuki
0
940
実践Claude Code:20の失敗から学ぶAIペアプログラミング
takedatakashi
18
8.9k
Devoxx BE - Local Development in the AI Era
kdubois
0
140
他言語経験者が Golangci-lint を最初のコーディングメンターにした話 / How Golangci-lint Became My First Coding Mentor: A Story from a Polyglot Programmer
uma31
0
440
Google Opalで使える37のライブラリ
mickey_kubo
3
150
React Nativeならぬ"Vue Native"が実現するかも?_新世代マルチプラットフォーム開発フレームワークのLynxとLynxのVue.js対応を追ってみよう_Vue Lynx
yut0naga1_fa
2
1.6k
AIと人間の共創開発!OSSで試行錯誤した開発スタイル
mae616
2
820
Vueのバリデーション、結局どれを選べばいい? ― 自作バリデーションの限界と、脱却までの道のり ― / Which Vue Validation Library Should We Really Use? The Limits of Self-Made Validation and How I Finally Moved On
neginasu
2
1.6k
Migration to Signals, Resource API, and NgRx Signal Store
manfredsteyer
PRO
0
120
はじめてのDSPy - 言語モデルを『プロンプト』ではなく『プログラミング』するための仕組み
masahiro_nishimi
4
16k
Featured
See All Featured
Site-Speed That Sticks
csswizardry
13
930
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
37
2.6k
The Language of Interfaces
destraynor
162
25k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
31
2.7k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.2k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Gamification - CAS2011
davidbonilla
81
5.5k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.1k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
Music & Morning Musume
bryan
46
6.9k
4 Signs Your Business is Dying
shpigford
185
22k
The Pragmatic Product Professional
lauravandoore
36
7k
Transcript
マルチモジュールな プロジェクトで テストはどう変わるか? Nozomi Takuma 2019/2/7 DroidKaigi2019
自己紹介 Nozomi Takuma SWET@DeNA所属 (2018/3~) Androidとテストが好き
はじめに
マルチモジュールって? :app :featureA :featureB アプリの実装を 複数のモジュールに 分割する
:app featueA package featureB package これまでのアーキテクチャ appモジュール内に 実装をまとめた モノリシックな構成
:app :featureA :featureB :app featueA package featureB package
app/build.gradle
なぜマルチモジュールにするのか? • 差分ビルドによるビルド時間短縮のため • App BundleやInstant App対応のため • それぞれの機能を分離させることで機能 間の独立性を保つため
マルチモジュールプロジェクトの テストで変わらないこと • テストを書くこと • テストの書きかた
マルチモジュールプロジェクトの テストで変わる3つのポイント 1. DI 2. テスト方針 3. メトリクス収集
DI
DI(Dependency Injection)って? • コンポーネントの依存を外から渡せる ようにする • テストをしやすくするためのパターン として利用される • DI
LibraryとしてDaggerが有名
マルチモジュールでのDI悩みポイント 1. モジュール間の依存関係を クリーンに保ちたい 2. 依存の定義をモジュール内で完結 させたい
モジュール間の依存をクリーンに保ちたい app module feature module 依存解決にapp module内のクラスが 必要な場合、循環参照が発生する可能性がある
Daggerで困る例
Daggerで困る例 feature module内の Activity app module内の Application
依存の定義をモジュール内で完結させたい • どのように依存が解決されるかの定義は モジュール内で完結できるとうれしい • DaggerでいうとModuleクラスの定義 など
マルチモジュールでのDI DIのやりかたやDIライブラリの使い方に よっては、前述の悩みポイントに対応する ため書き方や構成の変更が必要になる
話しきれないので... 『マルチモジュールプロジェクトでの Dagger2を用いたDependency Injection』 02/07 11:20 - 11:50@Hall A
サンプル • Dagger-Android https://github.com/tkmnzm/MultiModulePlayground
テスト方針
モジュール化によって得られるメリット • ビルド時間短縮による開発速度向上 • 意味のあるまとまりに分けることによって 他モジュールへの影響範囲が小さくなる
動作確認もモジュール内で完結 できるようにしたらどうだろう? モジュール化のメリットを得るために
モジュール内で動作確認を完結できると • 各モジュールの動作確認をするために 全体のapkをビルドしなくてよい • 動作確認済みのモジュールを使用する ことで、モジュールを結合したときの 動作確認が楽になる
モジュール内でどんな動作確認が できていたら嬉しいか? テスト方針を考える問いかけ
とあるモノリシックなプロジェクトの例 Presenter UseCase Repository 呼び出していることを 意味する矢印
とあるモノリシックなプロジェクトの例 Presenter UseCase Repository ユニット テスト
• レイヤー内の代表的なクラスのユニット テストは充実していた(UseCase,Repo など) • しかし上記以外の実装もたくさんあり テストが手薄なところもあった とあるモノリシックなプロジェクトの例
• このモジュールの動作確認はいまある テストだけだと足りない気がする... • この例の場合、UI部分やITテストが 不足していた モジュールとして分割してみた時
• まとまりの責務を考えるきっかけ • モノリシックなプロジェクトではレイ ヤーごとにどうテストするかを考える ことが多かったが、モジュール毎とい う新しい視点が生まれる モジュールとして切り出す
• モジュール内のテスト • モジュールをまたいだテスト モジュールのテスト方針を考えてみよう
モジュール内のテスト
モジュールの設計時に考えたいこと • モジュールの責務 • モジュールのテスト範囲
自動テストの手段はいろいろ ITテスト ユニット テスト UIテスト
例えばこんなモジュール① Utility Utility Utility
例えばこんなモジュール① Utility Utility Utility ユニット テスト
例えばこんなモジュール② Logic Logic Android PF
Logic Logic Android PF 例えばこんなモジュール② ユニット テスト IT テスト
Logic Logic Android PF 例えばこんなモジュール② IT テスト
例えばこんなモジュール③ Activity Logic Android PF
Activity Logic Android PF 例えばこんなモジュール③ UI テスト IT テスト
Activity Logic Android PF UI テスト 例えばこんなモジュール③
方針考えたけど何から手を付ける? ユニットテストで十分なところは ユニットテストからはじめる ユニット テスト
導入の容易さ ITテスト ユニット テスト UIテスト
FBサイクルの速さ ITテスト ユニット テスト UIテスト
ITテスト・UIテスト ユニットテストでは動作確認として 不足している部分に追加していく しかし、自分自身はAndroid PFが絡むテ ストは避けがちだった
ITテスト・UIテスト ユニットテストでは動作確認として 不足している部分に追加していく しかし、自分自身はAndroid PFが絡むテ ストは避けがちだった AndroidのAPIが絡むテストも導入しやすくなるよう 環境が変わりつつある
Project Nitrogen 実行環境の差分を統一した • API • Test Runner
API Robolectric上でも実機上でも実行可能
Test Runner
Project Nitrogenに期待すること • ローカルでのテスト: Robolectric上で素早く実行 • CIでのテスト: 実機やVirtual Device上など fidelity(忠実度)の高い環境で実行
None
現状は... • Robolectricで実行するには: src/testにテストコードを配置 • Deviceで実行するには: src/androidTestにテストコードを配置
ワークアラウンド
モジュール内のテストまとめ • モジュールの責務とテスト範囲を考える • まずはユニットテストからはじめる • ITテストやUIテストはつまづきがち だが、導入しやすい環境が整いつつある
もしテストを書く時間がなくても • テスタビリティは意識して実装したい • いざテストを書こうとしたときにテスト が書きにくい状態になっていると まずはリファクタリングが必要になる
モジュールをまたいだテスト
テストの方針 Module B Module A Module A Module B モジュールごとにテスト
結合してテスト
モジュールごとにテスト FeatureBをモック化
結合してテスト 実インスタンスや Spyを使用
モジュールをまたぐといっても • テストの書き方はいままでと変わらない • 他モジュールへの依存を外から渡すように していれば、これまでどおりテストダブル が使用できる
どれを選択する? • ケース・バイ・ケース • 自分のプロダクトではどんな不具合が起き やすいか?(単体でも拾える?結合しない とだめ?)というのは判断に使えそう
テストメトリクス収集
テストメトリクス Android開発でよく 使われているのは • JUnit実行結果 • Jacoco
マルチモジュールでのテストメトリクス収集 各モジュールのレポートをまとめて 見たい場合、結果のマージが必要
Jacocoについては... 『Spek2+MockK+JaCoCoでイケてるUnit Test環境を手に入れろ!』 02/08 11:20-11:50@Room 1
PIT Java、その他JVM言語用MutationTesting ツール http://pitest.org/
Mutation Testing • プロダクトコードを機械的に変更し、 変更されたコードに対してテストを実行 • テストが失敗するかを確認することで、 テストコードが振る舞いの変更を検知 できるかチェックする
例: Conditionals Boundary Mutator if (hoge <= 5) { //
do something } if (hoge < 5) { // do something } hogeが5のときの 振る舞いが Mutatorによって変更
例: Conditionals Boundary Mutator if (hoge <= 5) { //
do something } if (hoge < 5) { // do something } hogeが5のときの 振る舞いが Mutatorによって変更 hogeが5のときの テストが正しく書かれて いれば失敗するはず...
例: Conditionals Boundary Mutator テストを実行し... • テストが失敗する: OK • テストが成功する:
NG 境界値チェックなど、不足しているテストケースを 見つける手助けをしてくれる
PITのレポート
PITのレポート
PITのうれしいところ • Mutation Coverageと Line Coverageが見られる • Android用GradlePluginがある • Kotlinのサポートが進んでいる
実行結果のマージ: マージ処理抜粋
実行結果のマージ: PIT設定抜粋
サンプル https://github.com/tkmnzm/MultiModulePlayground • PIT導入 • PITレポートのマージ
まとめ
1. DI 2. テスト方針 3. メトリクス収集 まとめ • DIのやりかたによっては 書き方や構成の変更が必要
• 詳細はその他のDI関連 セッションで!
1. DI 2. テスト方針 3. メトリクス収集 まとめ • モジュール設計時に モジュールのテスト方針を
考えてみる • IT・UIテストもハードルが 下がりつつある
1. DI 2. テスト方針 3. メトリクス収集 まとめ • 各モジュールの結果を マージする必要がある
• 不足しているテストケース を見つけてくれるPITを ご紹介
ご清聴ありがとうございました