Share
Embed
「Chatwork」Android版アプリを 支える単体テストの現在
kubell.mobile #2 https://chatwork.connpass.com/event/337364/ での発表資料です。
okuzawats
December 11, 2024
Transcript
21 slides
-
事業概要 *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版の単体テストを支えるフレームワーク パターン① - JUnit 4 - Robolectric - Truth パターン②
- Kotest - MockK - Truth - Turbine -
パターン①: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テスト・統合テスト・単体テストそれぞれ の目的と内容を再定義していくことが、今後は必要になるかもしれない。