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

なぜテストを書くのか

 なぜテストを書くのか

社内向けにテストの意義等を紹介する際に用いたスライドです。
「なぜテストを書くのか」というところからはじまり、
Androidにおけるテストの基礎知識や、TDDについて紹介しています。

Hodaka Suzuki

April 10, 2019
Tweet

More Decks by Hodaka Suzuki

Other Decks in Technology

Transcript

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

    ハンズオン

    基礎編

    1

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  6. 目的
    6

    View Slide

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

    View Slide

  8. 効能
    8

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  34. テストをいつ書くのか
    34

    View Slide

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

    View Slide

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

    View Slide

  37. 1章まとめ
    37

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  41. テストの分類
    41

    View Slide

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

    View Slide

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

    View Slide

  44. さらに詳しく
    ● 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

    View Slide

  45. 詳細
    45

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  52. 2章まとめ
    52

    View Slide

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

    View Slide

  54. 3章
    テスト駆動開発
    54

    View Slide

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

    View Slide

  56. TDDとは
    56

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  60. TDDのゴール
    60

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  67. TDDの効能
    67

    View Slide

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

    View Slide

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

    View Slide

  70. TDDチュートリアル
    70

    View Slide

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

    View Slide

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

    View Slide