$30 off During Our Annual Pro Sale. View Details »
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
「Chatwork」Android版アプリを 支える単体テストの現在
Search
okuzawats
December 11, 2024
Programming
0
120
「Chatwork」Android版アプリを 支える単体テストの現在
kubell.mobile #2
https://chatwork.connpass.com/event/337364/
での発表資料です。
okuzawats
December 11, 2024
Tweet
Share
More Decks by okuzawats
See All by okuzawats
カンファレンス参加をいかに正当化するか
okuzawats
0
200
「勉強になった」で終わらせない、ストロングスタイルの勉強会
okuzawats
0
320
10年モノのAndroidアプリのコード品質を改善していく、3つの取り組み
okuzawats
0
1.1k
Androidアプリ開発におけるSonarCloudの活用
okuzawats
0
930
何故、UseCaseは1メソッドなのか
okuzawats
3
1.7k
例外を投げるな、値を返せ
okuzawats
9
7.6k
GitHub ActionsでAndroidアプリのテストを回しまくってたら全プロジェクトのCI/CDが完全停止する寸前だった件
okuzawats
0
470
Kotlinのifを愛でる
okuzawats
0
410
Say good-bye to Kotlin Android Extensions
okuzawats
0
230
Other Decks in Programming
See All in Programming
似たもの同士のPerlとPHP
uzulla
1
110
Seamless Flutter Native Integration: FFI & Pigeon - Dreamwalker (JaichangPark / 박제창) @FlutterKaigi2024
itsmedreamwalker
0
120
talk-with-local-llm-with-web-streams-api
kbaba1001
0
160
テスト自動化失敗から再挑戦しチームにオーナーシップを委譲した話/STAC2024 macho
ma_cho29
1
870
useSyncExternalStoreを使いまくる
ssssota
4
580
たのしいparse.y
ydah
3
110
Welcome JSConf.jp 2024
yosuke_furukawa
PRO
0
3.1k
これでLambdaが不要に?!Step FunctionsのJSONata対応について
iwatatomoya
0
230
これが俺の”自分戦略” プロセスを楽しんでいこう! - Developers CAREER Boost 2024
niftycorp
PRO
0
130
プロダクトの品質に コミットする / Commit to Product Quality
pekepek
1
700
layerx_20241129.pdf
kyoheig3
2
260
macOS なしで iOS アプリを開発する(※ただし xxx に限る)
mitsuharu
1
170
Featured
See All Featured
Building an army of robots
kneath
302
44k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
The Invisible Side of Design
smashingmag
298
50k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
890
How GitHub (no longer) Works
holman
310
140k
Git: the NoSQL Database
bkeepers
PRO
427
64k
Writing Fast Ruby
sferik
627
61k
4 Signs Your Business is Dying
shpigford
181
21k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Music & Morning Musume
bryan
46
6.2k
Imperfection Machines: The Place of Print at Facebook
scottboms
266
13k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
4
420
Transcript
「Chatwork」Android版アプリを 支える単体テストの現在 2024/12/11 kubell.mobile#2 奥澤俊樹
自己紹介 奥澤 俊樹(@okuzawats) Androidアプリエンジニア / 株式会社kubell ビジネスチャット「Chatwork」 Android版アプリを作っ ています。 髪の毛が伸びる速度が早すぎることが悩みです。
事業概要 *1 Nielsen NetView 及びNielsen Mobile NetView Customized Report 2024年4月度調べ月次利用者(MAU:Monthly
Active User)調査。 調査対象はChatwork、Microsoft Teams、Slack、LINE WORKS、Skypeを含む41サービスを株式会社kubellにて選定。 *2 2024年9月末時点。 • 国内最大級のビジネスチャット「Chatwork」を展開。 業界のパイオニアであり国内利用者数No.1*1、導入社数は60.5万社*2を突破 • 圧倒的な顧客基盤とプラットフォームを背景に、DXされた業務プロセスそのものを提供する クラウドサービス、BPaaSを展開 BPaaS (Business Process as a Service) ビジネスチャット「Chatwork」 お客様 オペレーター
「Chatwork」Android版アプリを 支える単体テストフレームワーク
「Chatwork」Android版アプリ
「Chatwork」Android版アプリ 「Chatwork」はサービス提供開始から10年が経過しており、多くの機能を提供している。 それに比例して複雑なドメイン・ビジネスのルールが存在する。 => 複雑なドメイン・ビジネスのルールに対して、仕様を明確に表す単体テストを書きた い。 ビジネスチャットを提供するアプリという性質上、頻繁に、かつ多量のデータを送受信する 必要がある。通信量やサーバー負荷を低減するために、クライアントサイドのローカルDBに 多くのデータをキャッシュして使用している。 =>
ローカルDBを使用する箇所に対して、信頼性の高い単体テストを書きたい。
「Chatwork」Android版アプリのモジュール構成(簡略版)
「Chatwork」Android版の単体テストを支えるフレームワーク パターン① - JUnit 4 - Robolectric - Truth パターン②
- Kotest - MockK - Truth - Turbine
「Chatwork」Android版アプリのモジュールごとのテストフレームワーク
パターン①:JUnit 4 + Robolectric + 他 - 依存オブジェクトをRobolectricのShadowに置き換えて、テスト対象オブジェクトの単 体テストをできるようにしている。 -
具体的には、テスト対象オブジェクトがSharedPreferenceやSQLiteへの依存を持 つ場合にこちらのパターンで単体テストを書く。 依存オブジェクトをRobolectricの Shadowに置き換える。
パターン②:Kotest + MockK + 他 - 依存オブジェクトをMockKを用いたスタブやスパイに置き換えて、テスト対象オブジェ クトの単体テストをできるようにしている。 - RobolectricのShadowが必要ない場合はこちらのパターンで単体テストを書く。
- 大部分の単体テストはこちらのパターンになる。 依存オブジェクトをMockKを用いた スタブやスパイに置き換える。
各パターンのメリット・デメリット JUnit 4 + Robolectric + 他 Kotest + MockK
+ 他 メリット エミュレータを用いずに、本来は端 末とのインタラクションが必要な処 理の単体テストを、信頼性高く書く ことができる。 Spec形式でテストケースを書くことで、 期待挙動・仕様が明確になる。 コンテキストを分けて、階層的にテスト ケースを書くことができる。 デメリット JUnit 4を用いている場合、一般的に モダンとされるテストコードの書き 方ができない場合がある。 特にKotestの学習コストが高い。 テストコードの書き方に自由度があり、 様々な書き方が混在してしまう。 テストダブルを多用することで単体テスト の信頼性を下げてしまう可能性がある。
単体テストのフレームワーク決定までの経緯 - 元々、JUnit 4で書かれた単体テストとKotestで書かれた単体テストが混在しており、 「どちらを使うべきかわからない」という意見があった。 - 保守・学習コストの観点から、ひとつのフレームワークに統一できることが好ましい。 - 「Spec形式でテストを書きたい、コンテキストごとにテストケースを階層化した い」(=
Kotestを使いたい)という要望あった。 - 機能開発チームはフルスタックなメンバー構成となっており、Spec形式に親 和性があった。 - 複雑なドメイン・ビジネスのルールに対して、仕様を明確に表すことのでき る表現力のある単体テストを書くことは確かに重要。 - 一方、KotestはRobolectricを用いることが難しいという制約があった。 - ローカルDBを使用する箇所はRobolectricを用いて信頼性の高いテストを書きた いので、そのために必須と言えるJUnit 4を使わない判断は難しかった。
単体テストのフレームワーク決定までの経緯 - 「Robolectricが必要な場合はJUnit 4 を、それ以外の場合はKotestを使用す る」という内容のアーキテクチャデシ ジョンレコード(ADR)を書き、メン バーの承認を得て、意思決定・意思統一 を行なった。 -
何故JUnit 4が必要なのか、何故 Kotestが必要なのか、意思決定の 記録を残した。
単体テストのフレームワーク決定までの経緯 - ADR承認後、ADRでの決定に従うように既存のテストコードを書き換えた。 - Robolectricが必要な単体テストはJUnit 4 + Robolectricで、Robolectricが必要 ない単体テストはKotest +
MockKで書くように統一した。 - 元々あった「どちらのフレームワークを使うべきかわからない」という課題につい ては、ADRで方針を明示したこと、既存コードをADRに従って修正したことで解消 できた。
JUnit 4とKotestを使い分けることで得られたこと メリット: - Robolectricを用いることによるデータ層の単体テストの信頼性向上 - Spec形式で単体テストを書くことによる単体テストによる仕様明確化の効果 - 特にドメイン層やViewModelの単体テストで効果大 -
新規メンバーから「期待挙動・仕様がわかりやすかった」とのコメント有 デメリット: - 複数のテストフレームワークを使用していることによる保守コスト・学習コストの増加 - Kotestのテストコードの書き方が統一されていないことによる、テストコードの可読性 ・保守性の低下 - テストコードが書かれた時期、書いたメンバーによって書き方に差がある。
テストピラミッドの観点から考える
テストピラミッドの観点から考える テストピラミッドの観点からは、現状統合テストが足りていない。 理想とされるテストピラミッド 現状のテストピラミッド
テストピラミッドの観点から考える E2Eテスト - 今年から自動化されたE2Eテストにも取り組んでいる。 - アドベントカレンダー見てね! - E2Eテストの導入当初に想定したテストシナリオについて、既に自動化されたテストが 存在する。 統合テスト
- 統合テストについては一部存在するものの、十分な取り組みを行うことができていない ため、今後の課題であると認識している。 - 統合テストの目的設定と、統合テストで何をテストするか?の整理は必要。 - E2Eテストを小さく保つため、E2Eテストの一部のテストシナリオを統合テス トで担保する、ということはあり得る。
まとめ
まとめ - JUnit 4 + Robolectric + 他、Kotest + MockK
+ 他を使い分けることによって、テス ト対象オブジェクトの特性に応じて最適な単体テストを書くことができるようになっ た。 - Kotestで(再び)Robolectricが動くようになると、テストフレームワークが統一 できて嬉しい。 - Kotestは様々なテストコードの書き方ができるため、テストコードが書かれた時期や書 いたメンバーによってテストコードの書き味に差異が出てしまった。 - この点はチームでも課題だと認識しており、今後改善していきたい。 - テストピラミッドの観点を取り入れて、E2Eテスト・統合テスト・単体テストそれぞれ の目的と内容を再定義していくことが、今後は必要になるかもしれない。