$30 off During Our Annual Pro Sale. View Details »

cookpad-summer-internship-2020-android

Kyohei Kato
August 24, 2020

 cookpad-summer-internship-2020-android

Kyohei Kato

August 24, 2020
Tweet

More Decks by Kyohei Kato

Other Decks in Technology

Transcript

  1. Cookpad
    Summer Internship 2020
    Android

    View Slide

  2. 講義の進め方
    ● わからないこと・知りたいことがあればいつでも Slack で聞いてください
    ● 講義中でも随時聞いてください
    ● 個人ごとに理解度の差があるかもしれませんが気にせず聞いてください
    ● 画面越しで困っている様子に気づけ無いかもしれないので積極的に聞いてくだ
    さい

    View Slide

  3. 自己紹介
    加藤 恭平
    2018年新卒入社
    技術部品質向上グループ → モバイル基盤部(イマココ)
    モバイルアプリの基盤技術 / ソフトウェア品質改善

    View Slide

  4. 自己紹介
    茂呂 智大
    2014年 中途入社
    モバイル基盤部 部長
    モバイルアプリ開発基盤の整備
    iOSの方が経験はあるのですが、 Androidでもがんばります!

    View Slide

  5. 参加メンバーで自己紹介
    ● 同じコースのメンバーに自己紹介をしましょう
    ○ 名前
    ○ 所属(大学など)
    ○ 好きなプログラミング言語
    ○ 好きな Android API
    ○ etc…

    View Slide

  6. クックパッドの
    アプリケーション開発手法を学ぶ

    View Slide

  7. クックパッドアプリの
    アーキテクチャとテスト手法に挑戦

    View Slide

  8. アーキテクチャとテスト手法を学ぶ
    ● ミニレシピアプリを題材にしてクックパッドアプリで採用されているアーキテクチャ
    を解説します
    ● 開発を進めながらアーキテクチャに沿ったテスト手法も合わせて解説します

    View Slide

  9. クックパッド Android アプリ
    ● 2014年ネイティブアプリとして初回リリース
    ● Kotlin: 約14万行, Java: 約10万行(2020年7月時点)
    ○ Activity: 約80, Fragment: 約100
    ● 複数の部署がコントリビュート
    ○ 基盤、広告、入会促進、投稿

    View Slide

  10. なぜアーキテクチャは必要なのか
    ● 同じ振る舞いをするプログラムでも無限の実現方法が存在する
    ○ 開発者全員が思い思いの実装をすれば多種多様なソースに
    ○ 自分以外が実装したコードは読める?持続的に開発可能?
    ○ xxManager, xxUtil, etc…
    ● 実現方法のルール(アーキテクチャ)を定義することで開発者同士で共通理解を
    持って実装を進める
    ○ ソフトウェアの全体像、構成要素、その関係性を明確にする

    View Slide

  11. 対戦相手: MiniCookpad
    ● https://github.com/cookpad/cookpad-internship-2020-summer-android
    ● レシピ一覧/詳細の閲覧、レシピ投稿ができるアプリ
    ○ レシピ投稿機能は未実装
    ● すべての処理が Activity/Fragment に記述されてしまっている
    ● バックエンドとして Firebase を利用

    View Slide

  12. Firebase
    ● Google 傘下のモバイル/Web向け開発プラットフォームサービス
    ● アプリケーションに必要な様々なサービスを提供
    ○ DB、ストレージ、アナリティクス、クラッシュ計測
    ● クックパッドでは Komerco が特に活用している
    ○ モバイル/Web 双方で活用
    ○ Firebaseで運用するKomercoの管理用アプリケーションの開発 - クックパッド開発者ブログ
    ■ https://techlife.cookpad.com/entry/2019/07/05/100000
    ○ KomercoアプリでFirebaseからの画像取得を速くした話 - クックパッド開発者ブログ
    ■ https://techlife.cookpad.com/entry/2018/11/02/100000

    View Slide

  13. 今回利用する Firebase サービス
    ● Cloud Firestore
    ○ https://firebase.google.com/docs/firestore
    ○ スケーラブルな NoSQL DB
    ○ リアルタイムリスナーやオフラインサポートなどの機能
    ○ レシピデータの保存
    ● Cloud Storage
    ○ https://firebase.google.com/docs/storage
    ○ 実態は GCP の Cloud Storage
    ○ メディアファイル等のコンテンツの管理
    ○ レシピ画像の保存

    View Slide

  14. アプリをビルドして触ってみよう

    View Slide

  15. アプリをビルドして触ってみよう
    ● https://github.com/cookpad/cookpad-internship-2020-summer-android
    ● リポジトリは fork して利用してください
    ● README に従ってセットアップを進めてください
    ● アプリをビルドして機能を確かめてください

    View Slide

  16. タイムスケジュール
    ● 1日目
    ○ 10:40 クックパッドのアーキテクチャ説明
    ○ 11:00 ハンズオン
    ○ 12:00 お昼
    ○ 13:00 ハンズオン続き
    ○ 13:50 ユニットテスト講義 + ハンズオン
    ○ 15:30 休憩
    ○ 15:45 UI テスト講義 + ハンズオン
    ○ 16:30 機能追加ハンズオン
    ○ 18:00 日報タイム
    ● 2日目
    ○ 10:00 ハンズオン続き(+ 発展課題)

    View Slide

  17. クックパッドアプリの
    アーキテクチャ

    View Slide

  18. Android アプリにおけるアーキテクチャ
    ● 公式で推奨アーキテクチャを紹介
    ○ https://developer.android.com/jetpack/docs/guide#common-principles
    ● 他にも様々なアーキテクチャが存在
    ○ MVC、MVVM、MVP…
    ● アプリの特性や開発スタイルなど目的に合わせて選定、唯一解はない
    ● クックパッド内でもプロジェクトによって様々

    View Slide

  19. レイヤードアーキテクチャ
    ● 責務ごとに関心を分離
    ○ UI 操作、ビジネスロジック、サーバとの通信、 DB との通信
    ● 分離した実装を層(レイヤー)のように積み重ねる
    参考: https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch01.html

    View Slide

  20. VIPER アーキテクチャ
    ● レイヤードアーキテクチャの一種
    ○ View, Interactor, Presenter, Entity, Routing からなるアーキテクチャ
    ● 2017年ごろからクックパッドアプリ(Android/iOS)で採用
    ○ プラットフォームの進化に合わせて持続的に開発可能なアーキテクチャとして採用
    ○ https://speakerdeck.com/uzzu/evolutionary-architecture

    View Slide

  21. VIPER #とは
    ● iOS アプリにおいて提唱されたアーキテクチャ
    ○ https://cheesecakelabs.com/blog/ios-project-architecture-using-viper/
    ● View, Interactor, Presenter, Entity, Routing をレイヤーとして分離
    ○ 社内では1組のセットを Scene(シーン) と呼んでいます
    ○ ほどんどの場合 1画面 <-> 1VIPER Scene
    ● VIPER の各レイヤーを Contract (契約)として定義
    ● Interactor から先を更にレイヤー分離
    ○ クックパッドアプリでは複数レイヤーが存在するが今回は DataSource のみ
    ○ DataSource: データを取得する層 (DB, サーバ)

    View Slide

  22. 追加

    View Slide

  23. View Slide

  24. 各レイヤーの解説
    ● View
    ○ UI の更新を担当、Android では主に Activity/Fragment
    ● Interactor
    ○ ビジネスロジックを担当、 Data Layer とやり取り
    ● Presenter
    ○ View からイベントを受け取り各レイヤーとやり取りする、調整担当

    View Slide

  25. 各レイヤーの解説
    ● Entity
    ○ 扱うデータの構造、レシピ一覧画面ではレシピデータ
    ● Routing
    ○ 画面遷移を担当
    ● Contract
    ○ 各レイヤーの定義(インタフェース)をまとめたもの

    View Slide

  26. 例: レシピ一覧画面
    ● 起動時にレシピ一覧を表示
    ○ サーバ(Firebase)からデータを取得
    ● レシピをタップするとレシピ詳細を表示
    ○ レシピ名、作者名、作り方を表示

    View Slide

  27. レシピ一覧を表示する流れ
    1. レシピ一覧をリクエスト
    6. 画面を更新
    2. データをリクエスト 3. データをリクエスト
    4. Entity に整形して返却
    5. データを View に渡す

    View Slide

  28. レシピ一覧をタップした際の流れ
    1. タップイベントを通知
    2. 画面遷移をリクエスト
    3. 画面遷移を実行

    View Slide

  29. VIPER アーキテクチャハンズオン
    ● レシピ一覧画面を VIPER アーキテクチャに書き換えてみよう
    ○ ハンズオンではコミットを忘れずに
    ○ ハンズオンが終われば次の内容進んで良いですが、質問には対応できません

    View Slide

  30. ユニットテスト

    View Slide

  31. Android におけるテスト
    ● https://developer.android.com/training/testing/fundamentals
    ● テストは主に2種類
    ○ 1. JVM 環境でのテスト
    ○ 2. Android 実行環境でのテスト
    ● 違いは実行環境の差異
    ○ Android は通常の JVM™ とは異なる
    ○ Android API は Android 実行環境を前提としているので JVM 上では動作しない

    View Slide

  32. VIPER のユニットテスト
    ● 各レイヤー間はインターフェースを介してやりとりするのでテストが容易に書け
    る!!!
    ○ 依存オブジェクトをモック (模倣)にすり替えることで挙動をコントロール可能
    ○ 例: DataSource をモックして Interactor のテストを実装
    ● JUnit + Mockito + Truth という構成で実装
    ○ JUnit: Java で実装されたテストフレームワーク
    ○ Mockito: モックを作成するフレームワーク
    ○ Truth: Google 製のアサーションライブラリ

    View Slide

  33. ユニットテストの基礎
    ● ユニットテストでチェックしたい内容を確認
    ○ 例: DataSource から値が正しく返って来た場合の Interactor の挙動を確認したい
    ● GWT (Given, When, Then)に沿って実装
    ○ テスト実行に必要な状況を構築 (Given)
    ■ 必要なオブジェクトを用意 (mock を駆使)
    ○ 確認したい振る舞いを実行 (When)
    ■ テストしたいメソッドの実行
    ○ 実行した内容に合わせて状況の確認 (Then)
    ■ 値のアサーション

    View Slide

  34. ユニットテストハンズオン
    ● 実装したレシピ一覧の Interactor と Presenter のテストを書いてみよう

    View Slide

  35. 休憩

    View Slide

  36. UI テスト

    View Slide

  37. View のテストはどうするか
    ● VIPER のうち View に関してはテスト実装が難しい
    ○ View の役割を担う Activity/Fragment は OS 側でインスタンスが管理されている
    ○ Android API を利用しているため JVM ではテストが実行できない
    ○ UI テストでは様々な要素が組み合わさるため実行が不安定になることも
    ● 不安定な要素を排除することでテストする内容に集中できるようにする
    ○ VIPER の場合 Presenter をモックすることで、 View に対してテストを実装可能

    View Slide

  38. Android の UI テスト
    ● https://developer.android.com/training/testing/ui-testing
    ● ターゲットアプリに干渉可能なテストアプリを端末にインストールし、アプリを操作
    しながらテストを実行する
    ○ テストアプリからターゲットアプリのコンテキストにアクセス可能
    ● Espresso という UI テストツールが主流
    ○ UI 操作、アサーションを担う
    ○ 内部実装は UIAutomator

    View Slide

  39. UI テストハンズオン
    ● レシピ一覧のレシピがタップされた場合の挙動を UI テストでチェック

    View Slide

  40. 投稿機能

    View Slide

  41. レシピ投稿画面を実装してみよう
    ● 既に定義されたレイアウトを利用してレシピデータの投稿機能を実装し、テスト
    まで実装してみよう

    View Slide

  42. 発展課題
    ● 新しい概念 DataStore を学びながら隠されたログイン機能を実装してみよう

    View Slide