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
cookpad-summer-internship-2020-android
Search
Kyohei Kato
August 24, 2020
Technology
0
8.1k
cookpad-summer-internship-2020-android
Kyohei Kato
August 24, 2020
Tweet
Share
More Decks by Kyohei Kato
See All by Kyohei Kato
After Party DroidKaigi 2021
ksfee684
0
550
cookpad.apk#5
ksfee684
0
620
cookpad.apk#4
ksfee684
0
690
Testing in weekly release
ksfee684
0
830
UI テストで楽するための技術
ksfee684
0
490
Android における UI テスト設計戦略
ksfee684
2
1.1k
Espresso Driver を用いた Appium テストとその仕組み
ksfee684
0
6.7k
Other Decks in Technology
See All in Technology
ハノーバーメッセ2025座談会.pdf
iotcomjpadmin
0
160
Welcome to the LLM Club
koic
0
170
Observability infrastructure behind the trillion-messages scale Kafka platform
lycorptech_jp
PRO
0
140
ひとり情シスなCTOがLLMと始めるオペレーション最適化 / CTO's LLM-Powered Ops
yamitzky
0
420
Javaで作る RAGを活用した Q&Aアプリケーション
recruitengineers
PRO
1
110
Clineを含めたAIエージェントを 大規模組織に導入し、投資対効果を考える / Introducing AI agents into your organization
i35_267
4
1.6k
フィンテック養成勉強会#54
finengine
0
170
mrubyと micro-ROSが繋ぐロボットの世界
kishima
2
230
PHPでWebブラウザのレンダリングエンジンを実装する
dip_tech
PRO
0
200
強化されたAmazon Location Serviceによる新機能と開発者体験
dayjournal
2
210
250627 関西Ruby会議08 前夜祭 RejectKaigi「DJ on Ruby Ver.0.1」
msykd
PRO
2
270
rubygem開発で鍛える設計力
joker1007
2
190
Featured
See All Featured
Balancing Empowerment & Direction
lara
1
370
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Automating Front-end Workflow
addyosmani
1370
200k
Faster Mobile Websites
deanohume
307
31k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
46
9.6k
Designing for Performance
lara
609
69k
Making the Leap to Tech Lead
cromwellryan
134
9.3k
Speed Design
sergeychernyshev
32
1k
Navigating Team Friction
lara
187
15k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
Into the Great Unknown - MozCon
thekraken
39
1.9k
Adopting Sorbet at Scale
ufuk
77
9.4k
Transcript
Cookpad Summer Internship 2020 Android
講義の進め方 • わからないこと・知りたいことがあればいつでも Slack で聞いてください • 講義中でも随時聞いてください • 個人ごとに理解度の差があるかもしれませんが気にせず聞いてください •
画面越しで困っている様子に気づけ無いかもしれないので積極的に聞いてくだ さい
自己紹介 加藤 恭平 2018年新卒入社 技術部品質向上グループ → モバイル基盤部(イマココ) モバイルアプリの基盤技術 / ソフトウェア品質改善
自己紹介 茂呂 智大 2014年 中途入社 モバイル基盤部 部長 モバイルアプリ開発基盤の整備 iOSの方が経験はあるのですが、 Androidでもがんばります!
参加メンバーで自己紹介 • 同じコースのメンバーに自己紹介をしましょう ◦ 名前 ◦ 所属(大学など) ◦ 好きなプログラミング言語 ◦
好きな Android API ◦ etc…
クックパッドの アプリケーション開発手法を学ぶ
クックパッドアプリの アーキテクチャとテスト手法に挑戦
アーキテクチャとテスト手法を学ぶ • ミニレシピアプリを題材にしてクックパッドアプリで採用されているアーキテクチャ を解説します • 開発を進めながらアーキテクチャに沿ったテスト手法も合わせて解説します
クックパッド Android アプリ • 2014年ネイティブアプリとして初回リリース • Kotlin: 約14万行, Java: 約10万行(2020年7月時点)
◦ Activity: 約80, Fragment: 約100 • 複数の部署がコントリビュート ◦ 基盤、広告、入会促進、投稿
なぜアーキテクチャは必要なのか • 同じ振る舞いをするプログラムでも無限の実現方法が存在する ◦ 開発者全員が思い思いの実装をすれば多種多様なソースに ◦ 自分以外が実装したコードは読める?持続的に開発可能? ◦ xxManager, xxUtil,
etc… • 実現方法のルール(アーキテクチャ)を定義することで開発者同士で共通理解を 持って実装を進める ◦ ソフトウェアの全体像、構成要素、その関係性を明確にする
対戦相手: MiniCookpad • https://github.com/cookpad/cookpad-internship-2020-summer-android • レシピ一覧/詳細の閲覧、レシピ投稿ができるアプリ ◦ レシピ投稿機能は未実装 • すべての処理が
Activity/Fragment に記述されてしまっている • バックエンドとして Firebase を利用
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
今回利用する Firebase サービス • Cloud Firestore ◦ https://firebase.google.com/docs/firestore ◦ スケーラブルな
NoSQL DB ◦ リアルタイムリスナーやオフラインサポートなどの機能 ◦ レシピデータの保存 • Cloud Storage ◦ https://firebase.google.com/docs/storage ◦ 実態は GCP の Cloud Storage ◦ メディアファイル等のコンテンツの管理 ◦ レシピ画像の保存
アプリをビルドして触ってみよう
アプリをビルドして触ってみよう • https://github.com/cookpad/cookpad-internship-2020-summer-android • リポジトリは fork して利用してください • README に従ってセットアップを進めてください
• アプリをビルドして機能を確かめてください
タイムスケジュール • 1日目 ◦ 10:40 クックパッドのアーキテクチャ説明 ◦ 11:00 ハンズオン ◦
12:00 お昼 ◦ 13:00 ハンズオン続き ◦ 13:50 ユニットテスト講義 + ハンズオン ◦ 15:30 休憩 ◦ 15:45 UI テスト講義 + ハンズオン ◦ 16:30 機能追加ハンズオン ◦ 18:00 日報タイム • 2日目 ◦ 10:00 ハンズオン続き(+ 発展課題)
クックパッドアプリの アーキテクチャ
Android アプリにおけるアーキテクチャ • 公式で推奨アーキテクチャを紹介 ◦ https://developer.android.com/jetpack/docs/guide#common-principles • 他にも様々なアーキテクチャが存在 ◦ MVC、MVVM、MVP…
• アプリの特性や開発スタイルなど目的に合わせて選定、唯一解はない • クックパッド内でもプロジェクトによって様々
レイヤードアーキテクチャ • 責務ごとに関心を分離 ◦ UI 操作、ビジネスロジック、サーバとの通信、 DB との通信 • 分離した実装を層(レイヤー)のように積み重ねる
参考: https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch01.html
VIPER アーキテクチャ • レイヤードアーキテクチャの一種 ◦ View, Interactor, Presenter, Entity, Routing
からなるアーキテクチャ • 2017年ごろからクックパッドアプリ(Android/iOS)で採用 ◦ プラットフォームの進化に合わせて持続的に開発可能なアーキテクチャとして採用 ◦ https://speakerdeck.com/uzzu/evolutionary-architecture
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, サーバ)
追加
None
各レイヤーの解説 • View ◦ UI の更新を担当、Android では主に Activity/Fragment • Interactor
◦ ビジネスロジックを担当、 Data Layer とやり取り • Presenter ◦ View からイベントを受け取り各レイヤーとやり取りする、調整担当
各レイヤーの解説 • Entity ◦ 扱うデータの構造、レシピ一覧画面ではレシピデータ • Routing ◦ 画面遷移を担当 •
Contract ◦ 各レイヤーの定義(インタフェース)をまとめたもの
例: レシピ一覧画面 • 起動時にレシピ一覧を表示 ◦ サーバ(Firebase)からデータを取得 • レシピをタップするとレシピ詳細を表示 ◦ レシピ名、作者名、作り方を表示
レシピ一覧を表示する流れ 1. レシピ一覧をリクエスト 6. 画面を更新 2. データをリクエスト 3. データをリクエスト 4.
Entity に整形して返却 5. データを View に渡す
レシピ一覧をタップした際の流れ 1. タップイベントを通知 2. 画面遷移をリクエスト 3. 画面遷移を実行
VIPER アーキテクチャハンズオン • レシピ一覧画面を VIPER アーキテクチャに書き換えてみよう ◦ ハンズオンではコミットを忘れずに ◦ ハンズオンが終われば次の内容進んで良いですが、質問には対応できません
ユニットテスト
Android におけるテスト • https://developer.android.com/training/testing/fundamentals • テストは主に2種類 ◦ 1. JVM 環境でのテスト
◦ 2. Android 実行環境でのテスト • 違いは実行環境の差異 ◦ Android は通常の JVM™ とは異なる ◦ Android API は Android 実行環境を前提としているので JVM 上では動作しない
VIPER のユニットテスト • 各レイヤー間はインターフェースを介してやりとりするのでテストが容易に書け る!!! ◦ 依存オブジェクトをモック (模倣)にすり替えることで挙動をコントロール可能 ◦ 例:
DataSource をモックして Interactor のテストを実装 • JUnit + Mockito + Truth という構成で実装 ◦ JUnit: Java で実装されたテストフレームワーク ◦ Mockito: モックを作成するフレームワーク ◦ Truth: Google 製のアサーションライブラリ
ユニットテストの基礎 • ユニットテストでチェックしたい内容を確認 ◦ 例: DataSource から値が正しく返って来た場合の Interactor の挙動を確認したい •
GWT (Given, When, Then)に沿って実装 ◦ テスト実行に必要な状況を構築 (Given) ▪ 必要なオブジェクトを用意 (mock を駆使) ◦ 確認したい振る舞いを実行 (When) ▪ テストしたいメソッドの実行 ◦ 実行した内容に合わせて状況の確認 (Then) ▪ 値のアサーション
ユニットテストハンズオン • 実装したレシピ一覧の Interactor と Presenter のテストを書いてみよう
休憩
UI テスト
View のテストはどうするか • VIPER のうち View に関してはテスト実装が難しい ◦ View の役割を担う
Activity/Fragment は OS 側でインスタンスが管理されている ◦ Android API を利用しているため JVM ではテストが実行できない ◦ UI テストでは様々な要素が組み合わさるため実行が不安定になることも • 不安定な要素を排除することでテストする内容に集中できるようにする ◦ VIPER の場合 Presenter をモックすることで、 View に対してテストを実装可能
Android の UI テスト • https://developer.android.com/training/testing/ui-testing • ターゲットアプリに干渉可能なテストアプリを端末にインストールし、アプリを操作 しながらテストを実行する ◦
テストアプリからターゲットアプリのコンテキストにアクセス可能 • Espresso という UI テストツールが主流 ◦ UI 操作、アサーションを担う ◦ 内部実装は UIAutomator
UI テストハンズオン • レシピ一覧のレシピがタップされた場合の挙動を UI テストでチェック
投稿機能
レシピ投稿画面を実装してみよう • 既に定義されたレイアウトを利用してレシピデータの投稿機能を実装し、テスト まで実装してみよう
発展課題 • 新しい概念 DataStore を学びながら隠されたログイン機能を実装してみよう