Upgrade to Pro — share decks privately, control downloads, hide ads and more …

なぜテストを書くのか

 なぜテストを書くのか

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

693ed679c8dde3eccbc682ff44f357e1?s=128

Hodaka Suzuki

April 10, 2019
Tweet

Transcript

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

    Co., Ltd. Androidテスト
 ハンズオン
 基礎編
 1
  2. 自己紹介 • 鈴木 穂高(すずき ほだか) Twitter: @hoddy3190 • 経歴 −

    2014年新卒入社 − 2014年8月〜 FFRK JP − サーバー、クライアント、マスター管理ツール、インフラ整備、マネジメントなど − 2018年10月〜 SWET − Androidテストチーム(テストの普及のための活動) − GTRチーム(仕様品質を向上させるための技術的なアプローチ研究) − https://speakerdeck.com/hoddy3190/xing-shi-shou-fa-nituitediao-betemita 2
  3. アジェンダ • 1章: なぜテストを書くのか − テストの目的 − テストの効能 − 各ロールへのメリット・デメリット

    − テストがないことによるリスク − テストをいつ書くのか − まとめ • 2章: Androidにおけるテストの紹介 − テストの分類 − 詳細 − まとめ • 3章: テスト駆動開発 − TDDとは − TDDの効能 − TDDチュートリアル 3
  4. 1章 なぜテストを書くのか 4

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

  6. 目的 6

  7. 自動テストの目的 7 • 効率的かつ効果的な品質担保 & 向上 − その結果 − ユーザーからの信頼獲得につながる

    − QA工数や手戻りが減る • 生産性向上 − その結果 − 時間的、精神的余裕ができる • 開発への指標の導入 − その結果 − スケジュール調整やプロセス改善の根拠に説得力が増し、 コミュニケーションコストが下がる
  8. 効能 8

  9. 効能一覧 • 自動テスト自体の効能 − 動作確認が自動化される − 動作確認手順がテストコードとして明文化される − 動作確認の結果をフォーマット化された形で出力できる −

    CIを有効に活用できる − 開発初期に不具合を発見することができ、 手戻り時間を減らすことができる • テストを書く過程で得られる効能 − より良質な設計に気付ける − 仕様への理解が深まる 9 品質向上 生産性向上 品質向上 指標 品質向上 生産性向上 品質向上 生産性向上 品質向上 生産性向上
  10. 効能詳細(動作確認自動化) 10 実装 実機確認 修正 実機確認 修正 実機確認 実装 普通の開発

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

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

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

    修正 テスト 修正 テスト実行 実機確認 普通の開発 テストを活用した開発 テスト実装 動作確認を自動化することで、生産性UP!
  14. 効能詳細(指標としてのテスト) • 進捗管理として活用 − あらかじめQAないしは開発チーム側でテストケースを用意する − エンジニアは、通ったテストの割合を進捗の指標として使える − QAは、通ったテストの割合を品質担保の指標として使える 14

    このテストケースをすべて通ったら QA検証ができるとみなします。 現在のテスト項目の消化は 6割です。今のところ順調です! エンジニア PM QA
  15. 効能詳細(良質な設計への気付き) 15 Presenter の Unit Test 書きたいんだけど、 Repository の挙動の影響を受けてて テスト書きにくいな...

    プロダクトコードを使用して テストを書こうとすることで、 設計の悪いところに気づける
  16. 効能詳細(良質な設計への気付き) 16 そうだ、依存関係なくせばいいんだ! ついでに、Repostory も Interface 化しよう! 良い設計の定義は難しいですが、この例では単に 依存関係がなくなったか否かととらえてください。

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

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

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

    日本語仕様 テストケース考案 テストケースを考える過程を踏むと 自ずと仕様に深入りできる
  20. 効能詳細(仕様への理解) • 書いたテストコードは資産として残る − 他の人の仕様の理解を助けるかもしれない − 日本語仕様を見る − 曖昧 −

    ソースコードを見る − 長い − テストコードを見る − !! − PRレビューで読むコードの量が減る といった効果も...! − 必要なことが考慮されているのかを、テストコードを見て判断できる − レビューとは直接関係ないコードの理解への助けになる 20 ※最近のテストケースは日本語で書かれることも
  21. 各ロールへのメリット・デメリット 21

  22. エンジニアへのメリット・デメリット • メリット − コードレビューにかかる時間を短縮できる − テストコードを読むことで仕様の理解を助長できる場合がある − 自身の設計の良し悪しをほかの人の力なしに批評しやすくなる −

    仕様の理解を実装する前に固められる − 動作確認を効率化できる − テストがないという引け目を感じなくて済む − ミスしているかもという心配がなくなる 22
  23. エンジニアへのメリット・デメリット • デメリット − 良いテストを書けるようになるまで教育コストが発生する − テストを書いている時間を本質的ではないと感じる − 注意を払わないと闇雲なテストになって、むしろ実装効率が落ちる −

    仕様が変わったときに既存のテストコードに影響が出ることがある 23
  24. PMへのメリット・デメリット • メリット − 実装者自身の報告より客観的な進捗の指標を入手できる − 手戻りが減ることにより、スケジュールどおりに進行できる確率が上がる • デメリット −

    テストという活動に対する意図と性質への理解が必要になる(特にエンジニア 出身ではないPMの人にとってはハードルかもしれない) 24
  25. QAへのメリット・デメリット • メリット − QAが可能であるか否かの検査をより具体的にできるため、 バグに引きづられてQA検証が停滞するといったような事態が減る − 結果、コスト削減か製品を批評するテストへの集中を選べるようになる − なにか不審な挙動を確認したとき、要求仕様とテストレポートの差異

    から原因に見当をつけやすくなる • デメリット − 特になし 25
  26. 企画へのメリット・デメリット • メリット − 考えた施策がより短時間で実現できるようになる − スケジュールどおりに施策を開始できる確率が上がる − 考えた仕様をそのまま実現できる確率が上がる −

    仕様の漏れや矛盾がより早いタイミングで返ってくるようになる • デメリット − 特になし 26
  27. 補足 27 これらのメリット・デメリットの享受は、 自動テストがうまくいっている状態であることが前提です。

  28. 自動テストがうまくいっている状態とは • テストが書きやすいプロダクトコードになっている − テストしづらくても、プロダクトコードの修正により解決ができる • テスト実行時間が短時間で終了する • テスト実行が自動で実行される(CI) •

    過不足なくテストケースを実装できている • テスト安定性に配慮できる − 擬似乱数や日時系の API にテストが影響されると、テストが非常に不安定に なる。テストコード側から指示できるような設計にすることでこれを回避できる。 28
  29. テストがないことによる 各ロールへのリスク 29

  30. テストがないことによるエンジニアへのリスク • リファクタの難易度があがる − デグレを検知しにくくなる − 精神的な負担も大きくなる − デグレが怖い→コピペして改変→似たようなコードが増える→ さらに変更の難易度が上がる

    • レビュー項目が増える • コードの読み解きに時間がかかる • 設計の質に関する保証がなくなる • 後になればなるほどテストの導入コストがあがる 30
  31. テストがないことによるPMへのリスク • 実装の考慮漏れが多くなり、スケジュール調整に 追われやすくなる 31

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

    仕様の調整コストに追われやすくなる − スケジュールの遅延が起きやすくなる 32
  33. テストがないことによるQAへのリスク • 品質が担保されていない状態でQAに入ることにより、検証工 数や起票工数が大きくなる 33

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

  35. 手戻り工数の大きさ • 開発初期にバグ発見をした場合 − ステークホルダーも少なく、仕様も検討段階であることが多いため、 仕様調整の工数は比較的小さい • 開発後期にバグ発見をした場合 − 多くのステークホルダーと調整の上、仕様が成り立っているため、

    バグ FIX に伴う仕様調整の対応工数が大きい • QA中にバグ発見をした場合 − QAの起票コストや、バグ FIX に伴う仕様の調整のコストなど さらに対応工数がかかる 35 後になればなるほど手戻り工数は大きくなる
  36. テストをいつ書くのか • 開発期間のいつ書くか − PRを出すときに成果物としてテストもほしい − 前述したとおり、関わるステークホルダーが小さいうちにテストを 書いておくと効果が大きくなる − ※

    ATDD のような開発では開発初期にテストを書く場合もある • プロダクトコードを書く前か後か − テストのメリット・デメリットを考えたうえでいつ書くのかを決める。 − 例: 良い設計が思いつかない場合 − プロダクトコードの前にテストを書くと、良い設計に気づけるかもしれない − 例: プロト開発期間など、スピードを求められている場合 − スクラップ&ビルドが落ち着いたあとでテストを書くと、スピードを落とさずにある程度の 品質を得られる(テストを書かないという選択もありえる)。 36
  37. 1章まとめ 37

  38. 1章まとめ 38 • テストの効能やメリット、デメリットを把握した上で、テストとの 関わり方を決めましょう • テストを書くこと自体はコストですが、 長期的な目線を持った上でペイするかどうか 判断しましょう −

    cf. テストがなかった無法地帯にテストを導入して開発速度を1.7倍にした話
  39. 2章 Androidにおけるテストの紹介 39

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

  41. テストの分類 41

  42. テストの分類 • 対象の結合度による分類 − unit test(単体テスト) − 1つのクラス/コンポーネントに閉じる − integration

    test(結合テスト) − 複数のクラス/コンポーネントにまたがる − UI test − 画面情報も含める 42
  43. Android テストの実行環境 • テスト実行環境 − local unit test − JVM上で実行する

    − instrumented test − 実機やエミュレータ上で実行する 43
  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
  45. 詳細 45

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

    46
  47. integration test • 複数のモジュールを組み合わせたときに正しく動作することを 検証するために行うテスト − Service や ContentProvider のようにユーザーが直接触れることが出来ず、

    かつ複数の画面にまたがって強調して動作するようなコンポーネントのテスト − サーバーに接続し REST API をクライアント側から検証するテスト 47
  48. UI test • ユーザーが実際にアプリのUI(ユーザーインターフェイス)を操 作したときに画面が正しく反応できるかといった内容を検証す るためのテスト − 「ボタンをクリックするとポップアップが表示される」 − 「規定文字数以上タイプすると送信ボタンが有効になる」

    48
  49. local unit test • jvm 上で実行するテストの手法 • 開発環境で直接高速に実行できる • Androidフレームワークに依存したテストが書きにくい

    テストを格納する場所は、app/src/test 配下 49 Robolectric を使うと、local unit test でも Androidフレームワーク依存のテストを実行することができるようにな ります。ただし、あくまで JVM上でMockしているだけなのでテストとしての信頼性は落ちます。
  50. instrumented test • 実機やエミュレーターを使ってテストを実行する手法 • Androidフレームワークを使わないとテストできないものは自 ずとこちらの手法を採用することになる • ビルドに時間がかかり、実行速度も local

    unit test に比べて 遅い テストを格納する場所は、app/src/androidTest 配下 50
  51. テストピラミッド(Google版。ご参考までに。) 51 https://developer.android.com/training/testing/fundamentals より

  52. 2章まとめ 52

  53. 2章まとめ 53 • Android でのテストには主に以下の分類がある − local unit test と

    instrumented test − unit test と integration test − ※Androidに限った話ではなく一般的な話 − それぞれの特徴に応じて使い分ける必要がある
  54. 3章 テスト駆動開発 54

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

  56. TDDとは 56

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

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

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

  60. TDDのゴール 60

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

    動作確認のサイクルが早い TDDとは 61
  62. 1. 次の目標を考える 2. その目標を示すテストを書く 3. そのテストを実行して失敗させる(Red) 4. 目的のコードを書く 5. 2で書いたテストを成功させる(Green)

    6. Greenを維持したまま、 リファクタリングを行う(Refactor) 7. 1~6を繰り返す TDDのサイクル 62
  63. t_wada さんの「50分でわかるテスト駆動開発 」より TDDのゴール 63

  64. • 動作するきれいなコードを目指す − きれい = 単一責務でシンプルなコード • プロダクト/テストコードをきれいにする機会を 細かく設け、常にやり続ける •

    リファクタリングは設計・コードを「きれい」に するための試行錯誤フェーズ リファクタリング 64
  65. • 失敗したテストを通すためにしかコードを 書いてはいけない • 1つ以上の失敗があるとき、テストコードを 書いてはいけない • 失敗するテストを通す以上のコードを 書いてはいけない 厳密な人は上のようなルールに従ってTDDしています

    (補足)3つのルール 65 ルール出典: http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd
  66. • テスト書くってことはTDDはテスト手法だよね? − 開発手法です • 全てにテストコードを書かないといけないんだよね? − プロダクトのすべてをTDDで開発する必要はありません よくある誤解 66

  67. TDDの効能 67

  68. • プロダクトにテストを残すことにつながる − 自動テストの効能については、「なぜテストを書くのか」を参照 • 実装のゴールを明確にした上で、細かく確認しながら 進めるため、実装の手戻りが小さくなる − 不安の払拭にもつながる •

    テストを書く機会が増えることで、 様々な場面でテストをうまく使いこなせるようになる − 動かしたら遅いかも → テストする − デグレ起きないかな → テストする TDDの効能 68
  69. • リファクタを行い続けていくことで、 内部品質(保守性、可読性、テスト容易性 etc...)を 向上させやすくなる • テスト対象(関数など)の最初のユーザーに なることで、外部品質(可用性、利便性 etc...)を 向上させやすくなる

    − テストコードから初めてその関数を使用する = 試用ができるので、 その関数の使いにくさ等に気付けるし、使いにくいままプロダクト コードにリリースしてしまうということも防げる TDDの効能 69
  70. TDDチュートリアル 70

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

  72. • Androidテスト全書 − 著者:白山 文彦 外山 純生 平田 敏之 菊池 紘 堀江 亮介 −

    https://peaks.cc/books/android_testing • 50分でわかるテスト駆動開発 − 著者:和田卓人 − https://www.slideshare.net/decode2017/do03-50 − CC BY 4.0 に基づいて使用しています リファレンス 72