Slide 1

Slide 1 text

Apr 10, 2019 鈴木 穂高 | Hodaka Suzuki システム本部品質統括部SWETグループ DeNA Co., Ltd. Androidテスト
 ハンズオン
 基礎編
 1

Slide 2

Slide 2 text

自己紹介 ● 鈴木 穂高(すずき ほだか) Twitter: @hoddy3190 ● 経歴 − 2014年新卒入社 − 2014年8月〜 FFRK JP − サーバー、クライアント、マスター管理ツール、インフラ整備、マネジメントなど − 2018年10月〜 SWET − Androidテストチーム(テストの普及のための活動) − GTRチーム(仕様品質を向上させるための技術的なアプローチ研究) − https://speakerdeck.com/hoddy3190/xing-shi-shou-fa-nituitediao-betemita 2

Slide 3

Slide 3 text

アジェンダ ● 1章: なぜテストを書くのか − テストの目的 − テストの効能 − 各ロールへのメリット・デメリット − テストがないことによるリスク − テストをいつ書くのか − まとめ ● 2章: Androidにおけるテストの紹介 − テストの分類 − 詳細 − まとめ ● 3章: テスト駆動開発 − TDDとは − TDDの効能 − TDDチュートリアル 3

Slide 4

Slide 4 text

1章 なぜテストを書くのか 4

Slide 5

Slide 5 text

1章の目標 ● 自動テストの効能、メリット、デメリットを知る ● その上で、ご自身のプロダクトにどのように 適用するか少し考えてみる − もちろん、考えてみた結果「テストを適用しない」となるのもOKです 5 ※以降のページでは、特に断りが無い限り、「テスト」は「自動テスト」のことを指します。

Slide 6

Slide 6 text

目的 6

Slide 7

Slide 7 text

自動テストの目的 7 ● 効率的かつ効果的な品質担保 & 向上 − その結果 − ユーザーからの信頼獲得につながる − QA工数や手戻りが減る ● 生産性向上 − その結果 − 時間的、精神的余裕ができる ● 開発への指標の導入 − その結果 − スケジュール調整やプロセス改善の根拠に説得力が増し、 コミュニケーションコストが下がる

Slide 8

Slide 8 text

効能 8

Slide 9

Slide 9 text

効能一覧 ● 自動テスト自体の効能 − 動作確認が自動化される − 動作確認手順がテストコードとして明文化される − 動作確認の結果をフォーマット化された形で出力できる − CIを有効に活用できる − 開発初期に不具合を発見することができ、 手戻り時間を減らすことができる ● テストを書く過程で得られる効能 − より良質な設計に気付ける − 仕様への理解が深まる 9 品質向上 生産性向上 品質向上 指標 品質向上 生産性向上 品質向上 生産性向上 品質向上 生産性向上

Slide 10

Slide 10 text

効能詳細(動作確認自動化) 10 実装 実機確認 修正 実機確認 修正 実機確認 実装 普通の開発 テストを活用した開発

Slide 11

Slide 11 text

効能詳細(動作確認自動化の例) 11 実装 実機確認 修正 実機確認 修正 実機確認 実装 テスト実行 修正 テスト実行 修正 テスト実行 実機確認 普通の開発 テストを活用した開発 テスト実装

Slide 12

Slide 12 text

効能詳細(動作確認自動化の例) 12 実装 実機確認 修正 実機確認 修正 実機確認 実装 テスト実行 修正 テスト 修正 テスト実行 実機確認 普通の開発 テストを活用した開発 テスト実装 実機での動作確認は、 アプリをビルドして、 UI操作をする必要があるので、 時間がかかる。 自動テストでの動作確認は、 対象の機能のみ素早く実行可能なため、 時間がかからない。

Slide 13

Slide 13 text

効能詳細(動作確認自動化の例) 13 実装 実機確認 修正 実機確認 修正 実機確認 実装 テスト 修正 テスト 修正 テスト実行 実機確認 普通の開発 テストを活用した開発 テスト実装 動作確認を自動化することで、生産性UP!

Slide 14

Slide 14 text

効能詳細(指標としてのテスト) ● 進捗管理として活用 − あらかじめQAないしは開発チーム側でテストケースを用意する − エンジニアは、通ったテストの割合を進捗の指標として使える − QAは、通ったテストの割合を品質担保の指標として使える 14 このテストケースをすべて通ったら QA検証ができるとみなします。 現在のテスト項目の消化は 6割です。今のところ順調です! エンジニア PM QA

Slide 15

Slide 15 text

効能詳細(良質な設計への気付き) 15 Presenter の Unit Test 書きたいんだけど、 Repository の挙動の影響を受けてて テスト書きにくいな... プロダクトコードを使用して テストを書こうとすることで、 設計の悪いところに気づける

Slide 16

Slide 16 text

効能詳細(良質な設計への気付き) 16 そうだ、依存関係なくせばいいんだ! ついでに、Repostory も Interface 化しよう! 良い設計の定義は難しいですが、この例では単に 依存関係がなくなったか否かととらえてください。

Slide 17

Slide 17 text

ユーザー名入力フォーム: 半角全角6文字まで 効能詳細(仕様への理解) 17 日本語仕様 テストケース考案

Slide 18

Slide 18 text

1. 6文字ぴったりはOKなのか 2. 6文字をオーバーしていたらどうするか 3. 入力された文字が空だったらどうするか ユーザー名入力フォーム: 半角全角6文字まで 効能詳細(仕様への理解) 18 日本語仕様 テストケース考案

Slide 19

Slide 19 text

1. 6文字ぴったりはOKなのか 2. 6文字をオーバーしていたらどうするか 3. 入力された文字が空だったらどうするか ユーザー名入力フォーム: 半角全角6文字まで 効能詳細(仕様への理解) 19 日本語仕様 テストケース考案 テストケースを考える過程を踏むと 自ずと仕様に深入りできる

Slide 20

Slide 20 text

効能詳細(仕様への理解) ● 書いたテストコードは資産として残る − 他の人の仕様の理解を助けるかもしれない − 日本語仕様を見る − 曖昧 − ソースコードを見る − 長い − テストコードを見る − !! − PRレビューで読むコードの量が減る といった効果も...! − 必要なことが考慮されているのかを、テストコードを見て判断できる − レビューとは直接関係ないコードの理解への助けになる 20 ※最近のテストケースは日本語で書かれることも

Slide 21

Slide 21 text

各ロールへのメリット・デメリット 21

Slide 22

Slide 22 text

エンジニアへのメリット・デメリット ● メリット − コードレビューにかかる時間を短縮できる − テストコードを読むことで仕様の理解を助長できる場合がある − 自身の設計の良し悪しをほかの人の力なしに批評しやすくなる − 仕様の理解を実装する前に固められる − 動作確認を効率化できる − テストがないという引け目を感じなくて済む − ミスしているかもという心配がなくなる 22

Slide 23

Slide 23 text

エンジニアへのメリット・デメリット ● デメリット − 良いテストを書けるようになるまで教育コストが発生する − テストを書いている時間を本質的ではないと感じる − 注意を払わないと闇雲なテストになって、むしろ実装効率が落ちる − 仕様が変わったときに既存のテストコードに影響が出ることがある 23

Slide 24

Slide 24 text

PMへのメリット・デメリット ● メリット − 実装者自身の報告より客観的な進捗の指標を入手できる − 手戻りが減ることにより、スケジュールどおりに進行できる確率が上がる ● デメリット − テストという活動に対する意図と性質への理解が必要になる(特にエンジニア 出身ではないPMの人にとってはハードルかもしれない) 24

Slide 25

Slide 25 text

QAへのメリット・デメリット ● メリット − QAが可能であるか否かの検査をより具体的にできるため、 バグに引きづられてQA検証が停滞するといったような事態が減る − 結果、コスト削減か製品を批評するテストへの集中を選べるようになる − なにか不審な挙動を確認したとき、要求仕様とテストレポートの差異 から原因に見当をつけやすくなる ● デメリット − 特になし 25

Slide 26

Slide 26 text

企画へのメリット・デメリット ● メリット − 考えた施策がより短時間で実現できるようになる − スケジュールどおりに施策を開始できる確率が上がる − 考えた仕様をそのまま実現できる確率が上がる − 仕様の漏れや矛盾がより早いタイミングで返ってくるようになる ● デメリット − 特になし 26

Slide 27

Slide 27 text

補足 27 これらのメリット・デメリットの享受は、 自動テストがうまくいっている状態であることが前提です。

Slide 28

Slide 28 text

自動テストがうまくいっている状態とは ● テストが書きやすいプロダクトコードになっている − テストしづらくても、プロダクトコードの修正により解決ができる ● テスト実行時間が短時間で終了する ● テスト実行が自動で実行される(CI) ● 過不足なくテストケースを実装できている ● テスト安定性に配慮できる − 擬似乱数や日時系の API にテストが影響されると、テストが非常に不安定に なる。テストコード側から指示できるような設計にすることでこれを回避できる。 28

Slide 29

Slide 29 text

テストがないことによる 各ロールへのリスク 29

Slide 30

Slide 30 text

テストがないことによるエンジニアへのリスク ● リファクタの難易度があがる − デグレを検知しにくくなる − 精神的な負担も大きくなる − デグレが怖い→コピペして改変→似たようなコードが増える→ さらに変更の難易度が上がる ● レビュー項目が増える ● コードの読み解きに時間がかかる ● 設計の質に関する保証がなくなる ● 後になればなるほどテストの導入コストがあがる 30

Slide 31

Slide 31 text

テストがないことによるPMへのリスク ● 実装の考慮漏れが多くなり、スケジュール調整に 追われやすくなる 31

Slide 32

Slide 32 text

テストがないことによる企画へのリスク ● 考えた施策が実現できる確率が下がる − コードのリファクタ難易度が上がることにより、 施策実装のために必要な工数が増え、 見積もった結果、工数的に難しいという結果になる可能性が高まる ● 実装の考慮漏れが起きやすくなる − 仕様の調整コストに追われやすくなる − スケジュールの遅延が起きやすくなる 32

Slide 33

Slide 33 text

テストがないことによるQAへのリスク ● 品質が担保されていない状態でQAに入ることにより、検証工 数や起票工数が大きくなる 33

Slide 34

Slide 34 text

テストをいつ書くのか 34

Slide 35

Slide 35 text

手戻り工数の大きさ ● 開発初期にバグ発見をした場合 − ステークホルダーも少なく、仕様も検討段階であることが多いため、 仕様調整の工数は比較的小さい ● 開発後期にバグ発見をした場合 − 多くのステークホルダーと調整の上、仕様が成り立っているため、 バグ FIX に伴う仕様調整の対応工数が大きい ● QA中にバグ発見をした場合 − QAの起票コストや、バグ FIX に伴う仕様の調整のコストなど さらに対応工数がかかる 35 後になればなるほど手戻り工数は大きくなる

Slide 36

Slide 36 text

テストをいつ書くのか ● 開発期間のいつ書くか − PRを出すときに成果物としてテストもほしい − 前述したとおり、関わるステークホルダーが小さいうちにテストを 書いておくと効果が大きくなる − ※ ATDD のような開発では開発初期にテストを書く場合もある ● プロダクトコードを書く前か後か − テストのメリット・デメリットを考えたうえでいつ書くのかを決める。 − 例: 良い設計が思いつかない場合 − プロダクトコードの前にテストを書くと、良い設計に気づけるかもしれない − 例: プロト開発期間など、スピードを求められている場合 − スクラップ&ビルドが落ち着いたあとでテストを書くと、スピードを落とさずにある程度の 品質を得られる(テストを書かないという選択もありえる)。 36

Slide 37

Slide 37 text

1章まとめ 37

Slide 38

Slide 38 text

1章まとめ 38 ● テストの効能やメリット、デメリットを把握した上で、テストとの 関わり方を決めましょう ● テストを書くこと自体はコストですが、 長期的な目線を持った上でペイするかどうか 判断しましょう − cf. テストがなかった無法地帯にテストを導入して開発速度を1.7倍にした話

Slide 39

Slide 39 text

2章 Androidにおけるテストの紹介 39

Slide 40

Slide 40 text

2章の目標 ● Android のテストで使う基本的な用語を押さえる 40

Slide 41

Slide 41 text

テストの分類 41

Slide 42

Slide 42 text

テストの分類 ● 対象の結合度による分類 − unit test(単体テスト) − 1つのクラス/コンポーネントに閉じる − integration test(結合テスト) − 複数のクラス/コンポーネントにまたがる − UI test − 画面情報も含める 42

Slide 43

Slide 43 text

Android テストの実行環境 ● テスト実行環境 − local unit test − JVM上で実行する − instrumented test − 実機やエミュレータ上で実行する 43

Slide 44

Slide 44 text

さらに詳しく ● local unit tests − local test + unit test = JVM 上で実行される単体テスト ● instrumented unit tests − instrumented test + unit test = 端末上で実行される単体テスト 44 Android 公式ドキュメント内におけるテストの呼び方例 https://developer.android.com/training/testing/unit-testing/local-unit-tests より ● Test apps on Android − https://developer.android.com/training/testing/index.html

Slide 45

Slide 45 text

詳細 45

Slide 46

Slide 46 text

unit test ● ソースコードの個々のユニットが意図した振る舞いを しているか検証するテスト − 自動テストの最も基礎的な単位でのテスト − クラスごとにメソッドが一定の入力に対して期待通りの出力を返すか、 呼び出しに応じてプロパティが適切に変化するかなどをテストする 46

Slide 47

Slide 47 text

integration test ● 複数のモジュールを組み合わせたときに正しく動作することを 検証するために行うテスト − Service や ContentProvider のようにユーザーが直接触れることが出来ず、 かつ複数の画面にまたがって強調して動作するようなコンポーネントのテスト − サーバーに接続し REST API をクライアント側から検証するテスト 47

Slide 48

Slide 48 text

UI test ● ユーザーが実際にアプリのUI(ユーザーインターフェイス)を操 作したときに画面が正しく反応できるかといった内容を検証す るためのテスト − 「ボタンをクリックするとポップアップが表示される」 − 「規定文字数以上タイプすると送信ボタンが有効になる」 48

Slide 49

Slide 49 text

local unit test ● jvm 上で実行するテストの手法 ● 開発環境で直接高速に実行できる ● Androidフレームワークに依存したテストが書きにくい テストを格納する場所は、app/src/test 配下 49 Robolectric を使うと、local unit test でも Androidフレームワーク依存のテストを実行することができるようにな ります。ただし、あくまで JVM上でMockしているだけなのでテストとしての信頼性は落ちます。

Slide 50

Slide 50 text

instrumented test ● 実機やエミュレーターを使ってテストを実行する手法 ● Androidフレームワークを使わないとテストできないものは自 ずとこちらの手法を採用することになる ● ビルドに時間がかかり、実行速度も local unit test に比べて 遅い テストを格納する場所は、app/src/androidTest 配下 50

Slide 51

Slide 51 text

テストピラミッド(Google版。ご参考までに。) 51 https://developer.android.com/training/testing/fundamentals より

Slide 52

Slide 52 text

2章まとめ 52

Slide 53

Slide 53 text

2章まとめ 53 ● Android でのテストには主に以下の分類がある − local unit test と instrumented test − unit test と integration test − ※Androidに限った話ではなく一般的な話 − それぞれの特徴に応じて使い分ける必要がある

Slide 54

Slide 54 text

3章 テスト駆動開発 54

Slide 55

Slide 55 text

3章の目標 ● TDDとはなにかを知る ● TDDを体験することを通じ、理解を深める 55

Slide 56

Slide 56 text

TDDとは 56

Slide 57

Slide 57 text

● Test Driven Developmentの略 ● 日本語に直すとテスト駆動開発 TDDって何の略? 57

Slide 58

Slide 58 text

t_wada さんの「50分でわかるテスト駆動開発 」より TDDのゴール 58

Slide 59

Slide 59 text

TDDのゴール 59 t_wada さんの「50分でわかるテスト駆動開発 」より

Slide 60

Slide 60 text

TDDのゴール 60

Slide 61

Slide 61 text

● 書いたプロダクトコードが意図通り動くか確認しながら細かく進 める(いたって普通の)開発 ● 特徴としては以下が挙げられる − プロダクトコードとテストコードを並行して書く − テストを先に書く − 動作確認のサイクルが早い TDDとは 61

Slide 62

Slide 62 text

1. 次の目標を考える 2. その目標を示すテストを書く 3. そのテストを実行して失敗させる(Red) 4. 目的のコードを書く 5. 2で書いたテストを成功させる(Green) 6. Greenを維持したまま、 リファクタリングを行う(Refactor) 7. 1~6を繰り返す TDDのサイクル 62

Slide 63

Slide 63 text

t_wada さんの「50分でわかるテスト駆動開発 」より TDDのゴール 63

Slide 64

Slide 64 text

● 動作するきれいなコードを目指す − きれい = 単一責務でシンプルなコード ● プロダクト/テストコードをきれいにする機会を 細かく設け、常にやり続ける ● リファクタリングは設計・コードを「きれい」に するための試行錯誤フェーズ リファクタリング 64

Slide 65

Slide 65 text

● 失敗したテストを通すためにしかコードを 書いてはいけない ● 1つ以上の失敗があるとき、テストコードを 書いてはいけない ● 失敗するテストを通す以上のコードを 書いてはいけない 厳密な人は上のようなルールに従ってTDDしています (補足)3つのルール 65 ルール出典: http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd

Slide 66

Slide 66 text

● テスト書くってことはTDDはテスト手法だよね? − 開発手法です ● 全てにテストコードを書かないといけないんだよね? − プロダクトのすべてをTDDで開発する必要はありません よくある誤解 66

Slide 67

Slide 67 text

TDDの効能 67

Slide 68

Slide 68 text

● プロダクトにテストを残すことにつながる − 自動テストの効能については、「なぜテストを書くのか」を参照 ● 実装のゴールを明確にした上で、細かく確認しながら 進めるため、実装の手戻りが小さくなる − 不安の払拭にもつながる ● テストを書く機会が増えることで、 様々な場面でテストをうまく使いこなせるようになる − 動かしたら遅いかも → テストする − デグレ起きないかな → テストする TDDの効能 68

Slide 69

Slide 69 text

● リファクタを行い続けていくことで、 内部品質(保守性、可読性、テスト容易性 etc...)を 向上させやすくなる ● テスト対象(関数など)の最初のユーザーに なることで、外部品質(可用性、利便性 etc...)を 向上させやすくなる − テストコードから初めてその関数を使用する = 試用ができるので、 その関数の使いにくさ等に気付けるし、使いにくいままプロダクト コードにリリースしてしまうということも防げる TDDの効能 69

Slide 70

Slide 70 text

TDDチュートリアル 70

Slide 71

Slide 71 text

別資料にて行います https://speakerdeck.com/hoddy3190/tddtiyutoriaru TDDチュートリアル 71

Slide 72

Slide 72 text

● Androidテスト全書 − 著者:白山 文彦 外山 純生 平田 敏之 菊池 紘 堀江 亮介 − https://peaks.cc/books/android_testing ● 50分でわかるテスト駆動開発 − 著者:和田卓人 − https://www.slideshare.net/decode2017/do03-50 − CC BY 4.0 に基づいて使用しています リファレンス 72