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

テスト駆動開発入門

yattom
September 29, 2018

 テスト駆動開発入門

テスト駆動開発(TDD)の入門です。
TDDBC Tokyo 2018の基調講演資料です。
(TDDBC当日の編集や、後日のフィードバックを反映しています。そのため基調講演時から一部変更されています。)

yattom

September 29, 2018
Tweet

More Decks by yattom

Other Decks in Programming

Transcript

  1. テスト駆動開発入門
    やっとむ
    2018.9.29 TDDBC Tokyo
    https://is.gd/oWSKeZ

    View Slide

  2. 安井 力 / やっとむ
    twitter:@yattom https://www.facebook.com/yattom
    プログラマー
    Java Python Ruby JavaScript
    テスト駆動開発
    アジャイルコーチ
    ワークショップ 現場導入 技術支援
    ゲームを作って一緒に遊ぶ
    宝探しアジャイルゲーム、
    カンバンゲーム、
    心理的安全性ゲーム

    View Slide

  3. View Slide

  4. テスト駆動開発 / TDD
    Test
    Driven
    Development
    why?

    View Slide

  5. Why Develop?

    View Slide

  6. Why Develop?
    • 実現したいことがあるのに、ソフトウェアがない
    • 今あるソフトウェアの変更、追加をしたい
    • プログラムを書くのは楽しい
    • 難しい

    View Slide

  7. Why Test?

    View Slide

  8. Why Test?
    • 思った通りにできたか知りたい
    • 問題がないか知りたい
    • 目的にかなっているか知りたい
    • 誰かに証明したい
    • バリデーション vs. ベリフィケーション
    • チェッキング vs. テスティング

    View Slide

  9. Why Test “Driven”?
    • フィードバック

    View Slide

  10. Development
    Test

    View Slide

  11. テスト駆動開発は
    ふつうの開発

    View Slide

  12. 実演: Hello World

    View Slide

  13. 復習
    • プロダクトコード (コード) = 書きたいプログラム
    • テストコード (テスト) = プロダクトコードを書くための自動化テスト

    View Slide

  14. View Slide

  15. View Slide

  16. 「動作するきれいなコード」、ロン・ジェフ
    リーズのこの簡潔な言葉が、テスト駆動開
    発(TDD)のゴールだ。動作するきれいな
    コードはあらゆる意味で価値がある。
    ─ Kent Beck

    View Slide

  17. 動作する、きれいなコードへ
    きれい
    汚い
    (すぐには)動かない 動作する

    View Slide

  18. 動作する、きれいなコードへ
    きれい
    汚い
    (すぐには)動かない 動作する
    二つの道がある

    View Slide

  19. TDDでサイクルにする
    きれい
    汚い
    (すぐには)動かない 動作する

    View Slide

  20. きれい
    汚い
    (すぐには)動かない 動作する
    Green
    Refactoring
    TDDと黄金の回転

    View Slide

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

    View Slide

  22. 実演: 計算機

    View Slide

  23. 計算機の仕様
    • 足し算ができる
    • [x] 引き算ができる
    • 掛け算ができる
    • [x] 割り算ができる
    • [x] 計算できないときはエラーにする

    View Slide

  24. 復習
    • 小さなステップで進める
    • TODOリストを作る
    • ユーザーの視点から設計を考える
    • 仮実装(Fake It) → 三角測量(Triangulation)
    • リファクタリングをする

    View Slide

  25. TODOリストとテスト
    • 大きな仕様を細かく分割する
    • 1つ1つのテストを、TODOを達成した証明にする
    • TODOリストは随時追加・変更・並び替えする
    • 作りながら仕様がより明確・詳細に理解されていく
    • 仕様(specification)とは詳細で明確(specific)なもの

    View Slide

  26. プログラムは「込み入った領域」で解く
    分割統治

    View Slide

  27. テスト駆動開発はふつう?
    テスト駆動開発の特徴
    • サイクルがとっても早い・短い
    • テストのほうを先に書く(「テストファースト」)
    • 必ずテストを書く
    以上を絶対視する原理主義者もいる
    多くの人は状況に応じて使い分ける

    View Slide

  28. Uncle Bob said …
    「クズコードを書くのは
    もうやめだ」
    「顧客のため
    最高のコードを書く」
    「上司のため
    最高のテストを書く」
    「チームのため
    すべてテストを書く」
    「上達するため
    練習を積む」 Software Craftsmanship: What it's all about.

    View Slide

  29. View Slide

  30. TDDは開発手法
    あるある:
    「あ、きみテスト駆動開発やったことあるの? じゃあテスト書けるね!」
    • テスト手法ではない!
    • プロダクションコードを書くために、テストコードも書く
    • 他の手法と組み合わせて使える

    View Slide

  31. アジャイルテスト 高品質を追求するアジャイルチームにおけるテストの視点 増田聡 Developer Summit 2010
    http://www.slideshare.net/satoshimasuda/ss-3241717

    View Slide

  32. 余談: TDDのテストはテストじゃない…?
    • TDD=開発手法≠テスト手法
    • でもテスト書いてるじゃんね
    • 単純な事実:
    TDDで書いたテストは
    必要なテストすべてを
    網羅しない可能性がある
    (網羅したかったら
    網羅するように
    書かないといけない)
    https://www.slideshare.net/goyoki/votddtdd-tdd-on-live

    View Slide

  33. • Fast
    • Independent
    • Repeatable
    • Self-
    Validating
    • Timely

    View Slide

  34. • 高速である
    • 独立している
    • 再現性がある
    • 自己検証可能
    • 適時性がある

    View Slide

  35. ここまでのまとめ ― TDDとは?
    • プロダクトコードとテストコードを並行して書く
    • 動くか確認しながら進める、ふつうの開発
    • TDDのサイクル = レッド・グリーン・リファクタリング
    • TODOリスト
    • TDDのテストと品質のテスト
    • F.I.R.S.T.

    View Slide

  36. Why TDD? ― TDDが解決する問題
    • テストがない
    • テストを書かない
    • ユーザー視点が欠ける
    • 最善の解を探せない
    • チーム内でやり方がバラバラ
    • 機能変更や追加が大変
    • 引き継ぎができない

    View Slide

  37. Why TDD? ― TDDの効果
    • テストがある
    • テストが書ける
    • ユーザー視点を持てる
    • 試行錯誤を通じて最善の設計に近づける
    • チームのレベルが上がる
    • 機能変更や追加が容易になる
    • 意図を残せる

    View Slide

  38. Why TDD? ― 人間の問題












    利用者の視点
    を持つ
    作業分担して
    協力する

    View Slide

  39. Why TDD? ― 人間の問題














    使い方を
    把握する

    View Slide

  40. Why TDD? ― 人間の問題


















    他の人に
    理解してもらう

    View Slide

  41. Why TDD? ― 人間の問題












    他の人に
    理解してもらう
    使い方を
    把握する
    利用者の視点
    を持つ
    作業分担して
    協力する
    動作する
    きれいなコード

    View Slide

  42. 余談 ― 結合の問題











    結合して
    テストする

    View Slide

  43. 余談 ― 結合の問題
    • テストレベル
    • ユニット ≒ 自分1人の仕事をテストする
    • 結合 ≒ 2人以上の仕事を組み合わせてテストする
    • システム ≒ 実際に使うユーザーの観点でテストする

    View Slide

  44. Why TDD? ― 変更容易性の問題
    ←プロダクトの死

    View Slide

  45. Why TDD? ― 変更容易性の問題
    • 設計が複雑化する
    • ドキュメントが陳腐化する
    • 全体を把握しきれなくなる
    • どこを直せばいいか自信がなくなる
    • 全体を理解していないので、つぎはぎで直す
    • 直した場所と関係なさそうなところが壊れる
    • ますます設計が複雑化する

    View Slide

  46. Why TDD? ― テストを残す
    • 将来たくさん変更するなら、毎回テストも必要
    • 大規模なプログラムでは、変更の影響範囲把握が難しい
    → テストは毎回、すべてやりたい
    回帰テスト
    • 質問: 将来に渡り、同じテストを100回やるとします
    手でやるのと、自動テストにするのと、どっちが好き?

    View Slide

  47. Why TDD? ― 不安を取り除く
    • 動くか不安 → テストする
    • 異常な入力でも平気だろうか → テストする
    • 動かしたら遅いかも → テストする
    • 新しい機能は、元からある機能と不整合しないかな? → テストする
    • このライブラリどう使うんだろう → テストする
    • 変なコードだけどどんな結果になるのかな → テストする
    • こう動くと思うんだけど → テストする
    • こう書けばいいのかな → テストする
    • 面倒くさいしこれでいいや → テストする
    • ねむいつかれたかえりたい → テストする

    View Slide

  48. 命綱を編む

    View Slide

  49. Why TDD? ― 楽しい!
    「書いたプログラムはちゃんと動くだろうか?」
    不安
    「ほらちゃんと動くわー おれすごいわー」
    楽しい

    View Slide

  50. ここまでのまとめ ― Why TDD?
    • 人間の問題
    • 変更容易性の問題
    • テストの自動化と回帰テスト
    • 不安に立ち向かう
    • 命綱を編む

    View Slide

  51. 実演: 素因数分解

    View Slide

  52. 素因数分解の分解
    • [ ] 1を素因数分解すると→1
    • [ ] 2を素因数分解すると→2
    • [ ] 6を素因数分解すると→2, 3
    • 3を素因数分解すると→3

    View Slide

  53. 素因数分解の分解
    • 1の場合(特殊)
    • [ ] 1を素因数分解すると→1
    • 素数の場合
    • [ ] 2を素因数分解すると→2
    • 3を素因数分解すると→3
    • 複合の場合
    • [ ] 6を素因数分解すると→2, 3

    View Slide

  54. 復習
    • テストファースト
    • 自分にとって不安がないように分割する
    • 分割した結果はTODOリストに残しておく
    • テストの中にロジックを書いて、後からコードに移してもよい

    View Slide

  55. リファクタリング
    • リファクタリング… きれいなコードを維持するための作業
    動作する
    きれいなコード

    View Slide

  56. きれい
    汚い
    (すぐには)動かない 動作する
    Green
    Refactoring
    TDDと黄金の回転
    動作する
    きれいなコード

    View Slide

  57. きれいを保つ
    http://www.flickr.com/photos/adwriter/226233780/

    View Slide

  58. リファクタリングの対象
    • コードをきれいにする
    • メソッド名、変数名
    • インデント
    • コメント
    • 設計も見直す
    • プロダクトコードもテストコードも見直す
    • 常にやり続ける
    • 「動くコード」を保証するテストが前提

    View Slide

  59. わたし「きれい」?
    http://pompom0809.hatenablog.com/entry/2016/10/24/205946

    View Slide

  60. わたし「きれい」?
    ○ きれいな部屋、きれいな机、きれいな作業スペース
    ×きれいな花、きれいな色、きれいな風景
    • 感覚ではなく、客観的なもの
    • 美醜ではなく、効率や安全に関わるもの
    • 「動作するもっともシンプルなコード」
    • 「もっともシンプル」に到達するには試行錯誤が必要
    • きれい、シンプルの基準は、スキルや経験による
    論理的

    View Slide

  61. リファクタリングは可逆変換
    • 変数名やメソッド名の変更
    • 処理の一部をメソッド化する ⇔ メソッドをインライン化する
    • 一時変数を導入する ⇔ 変数をインライン化する
    • データを移動する ⇔ オブジェクトをくくり出す ⇔ メソッドを移動する
    • 条件記述を分割する ⇔ 条件記述を統合する
    • その他いろいろ
    リファクタリングを使って
    「動作するもっともシンプルなコード」を
    模索する

    View Slide

  62. View Slide

  63. 実演: 素因数分解の
    リファクタリング

    View Slide

  64. 復習
    • 試行錯誤する
    • リファクタリング前後で見比べて、いい方を選ぶ
    • ツール(IDE)の機能を活用する

    View Slide

  65. TDDは設計手法?
    • 設計=決断
    • いくつも考えられる候補から1つ選ぶのが設計
    • ドキュメントを書くのが設計ではないよ!
    • コードを書く=大小様々な決断の連続
    • 意識せずに決断していることも
    • リファクタリングは決断を見直して、よりよい設計を見つける機会

    View Slide

  66. どの設計が好き? どれがきれい?

    View Slide

  67. きれい
    汚い
    (すぐには)動かない 動作する
    Green
    Refactoring
    きれいに到達する手段
    試行錯誤
    改善
    机上設計
    理想
    実験

    View Slide

  68. http://blog.cleancoder.com/uncle-bob/2014/12/17/TheCyclesOfTDD.html

    View Slide

  69. きれいに到達する手段 ― テストダブル
    依存コンポーネントを置き換え、テスト対象のコードを
    実行できる
    さらに、直接アクセスできない箇所を
    対象にしたアサーションができる
    • テストダブルの種類 (xUnit Patterns)
    • スタブ
    • モック
    • スパイ
    • フェイク

    View Slide

  70. すでにきれいじゃないときは
    • 直して祈る 保護して変更する
    • 「シーム(縫い目、接合部)」を見つける
    • 第6章 時間がないのに変更しなければなりません
    • 第9章 このクラスをテストハーネスに入れることができま
    せん
    • 第11章 変更する必要がありますが、どのメソッドをテスト
    すればよいのでしょうか?
    • 第16章 変更できるほど十分に私はコードを理解していま
    せん
    • 第21章 同じコードをいたるところで変更しています
    • 第24章 もうウンザリです。何も改善できません

    View Slide

  71. ここまでのまとめ ― リファクタリング
    • リファクタリングできれいを保つ
    • きれい=Clean 美醜ではない
    • TDDサイクルの一部として、常にやる
    • コードも、テストも、設計もリファクタリングする
    • 試行錯誤と設計の改善
    • 設計の道具としてのテストダブル

    View Slide

  72. TDDの
    こころ

    View Slide

  73. TDDの
    こころ
    テストに出ます!
    コードにも出ます!

    View Slide

  74. 一つずつ
    少しずつ
    段を
    小さく

    View Slide

  75. ひとりずつ
    対処する。
    複数を相手
    にしない。

    View Slide

  76. すばやく
    まわす

    View Slide

  77. 自分が最初の
    ユーザ

    View Slide

  78. 不安を
    テストに

    View Slide

  79. 祈るのではダメ

    View Slide

  80. 命綱を編む

    View Slide

  81. ここまでのまとめ ― TDDのこころ
    • ひとつずつ 少しずつ
    • 複数を相手にしない
    • すばやく回す
    • 自分が最初のユーザ
    • 不安をテストに
    • 祈るのではダメ
    • 命綱を編む

    View Slide

  82. テスト駆動開発の効果
    IBM
    ドライバ
    Microsoft
    Windows
    Microsoft
    MSN
    Microsoft
    VisualStudio
    チーム人数 9 6 5-7 7
    コード量(KLOC) 41.0 6.0 26.0 155.2
    開発規模(人月) 119 24 46 20
    欠陥数
    (TDD未使用に対
    する)
    61% 38% 24% 9%
    開発時間の増加
    (管理者の見積)
    15~20% 25~35% 15% 20~25%
    Nachiappan Nagappan, E. Michael Maximilien, Thirumalesh Bhat, Laurie Williams “Realizing
    quality improvement through test driven development: results and experiences of four
    industrial teams” 2008
    http://research.microsoft.com/en-us/groups/ese/nagappan_tdd.pdf

    View Slide

  83. TDDの効果の研究をまとめた研究
    "Effects of Test-Driven Development: A Comparative Analysis of
    Empirical Studies" Simo Makinen and Jurgen Munch
    • 既存の実証研究を調査し、10の内部・外部品質評価項目で、各研究
    の結論を整理した
    • TDDは欠陥の作り込み(introduced defects)を減らし、メンテナンス
    しやすいコードを産む
    • TDDで実装されたコードは、部分的に、サイズが小さく、複雑度が低
    い場合がある
    • メンテナンスがしやすくなるものの、初期開発では時間がかかる

    View Slide

  84. TDDの効果の研究をまとめた研究
    やっとむ TDD 検索

    View Slide

  85. TDDの効果(言い訳編)
    • テストを自動化できます!
    • 品質が良くなります!
    • テストがドキュメントの代わりになります!
    • 新しい人もすぐキャッチアップできます!
    • メンバーが抜けても大丈夫です!
    • 修正してもデグレません!
    • (手で)テストしなくてすみます!
    • 変更コストが下がります!
    ※用法、用量を守って安全に使いましょう

    View Slide

  86. TDDは
    スキルである
    http://www.flickr.com/photos/nicohogg/75040212/

    View Slide

  87. TDDは
    練習して上達する
    http://www.flickr.com/photos/risager/8388040402

    View Slide

  88. • テストを自動化できます!
    • 品質が良くなります!
    • テストがドキュメントの代わりになります!
    • 新しい人もすぐキャッチアップできます!
    • メンバーが抜けても大丈夫です!
    • 修正してもデグレません!
    • (手で)テストしなくてすみます!
    • 変更コストが下がります!
    ※用法、用量を守って安全に使いましょう
    TDDの効果(言い訳編)
    実践し実績で示す
    ・自分たちが
    ・自分の環境・状況で
    ・効果を出せること

    View Slide

  89. TDDのテストで「本当に必要なもの」を先に決める

    View Slide

  90. https://www.flickr.com/photos/emotakespictures/33245514280/
    行き先を示す
    道しるべ

    View Slide

  91. 足下を照らす
    明かり
    https://www.flickr.com/photos/menschmaschine/19898877294/

    View Slide

  92. 自分の
    歩幅で

    View Slide

  93. 実演: 自動販売機(設計進化重視版)
    お題1. ボタンを押すとコーラが出る
    •ボタンを押すとコーラが出ます。

    View Slide

  94. 実演: 自動販売機
    お題2. お金を払う
    •100円コインを投入してからボタンを押すと
    コーラが出ます。
    •100円コイン以外は投入できません。

    View Slide

  95. 実演: 自動販売機
    お題3. ウーロン茶追加
    •押したボタンに応じてコーラかウーロン茶が
    出ます。
    •他の飲み物も追加してみましょう。

    View Slide

  96. 本日のお題
    自動販売機(設計進化重視版)
    https://is.gd/uUk8kp

    View Slide

  97. 自動販売機(設計進化重視版)
    お題1. ボタンを押すとコーラが出る
    • ボタンを押すとコーラが出ます。
    お題2. お金を払う
    • 100円コインを投入してからボタンを押すとコーラが出ます。
    • 100円コイン以外は投入できません。
    お題3. ウーロン茶追加
    • 押したボタンに応じてコーラかウーロン茶が出ます。
    • 他の飲み物も追加してみましょう。
    お題4… 続く

    View Slide

  98. ペアプロのプロトコル
    はじめに
    1. あいさつしましょう
    2. ゴールとやることを決めましょう
    1. TODOリストを書く
    3. 役割を確認しましょう
    ペア作業中
    • ドライバーがコードを書く
    • なにをしているか、常に共有し続ける
    • タスクはひとつずつ片付けて、確認する
    • どんどん役割を交代する
    区切りで
    • やったことを見直しましょう
    • 方針を見直さなくていいか、確認しましょう
    • TODOリストの見直しと更新

    View Slide

  99. 本日のお題
    スーパーの支払金額
    https://is.gd/lsXS1B

    View Slide

  100. スーパーの支払金額
    スーパーで買い物したときの支払金額を計算する
    以下の商品リストがあるとする。先頭の数字は商品番号。
    1. りんご 100円
    2. みかん 40円
    3. ぶどう 150円
    4. のり弁 350円
    5. しゃけ弁 400円
    6. タバコ 420円
    7. メンソールタバコ 440円
    8. ライター 100円
    9. お茶 80円
    10. コーヒー 100円

    View Slide

  101. スーパーの支払金額
    以下の順番で、仕様を追加・実装していく。
    お題1 合計金額
    商品番号と個数を複数組、引数として受け取り、合計金額を計算する関数を書いてみよう。
    ヒント: 複数のものを受け取るために、配列やリストで一括で渡す方法がある。あるいは、1つ渡
    す関数を何回も呼び出して、最後に合計金額を計算する関数を呼び出すという形式もある。
    両方のアプローチをTDDで実装し見比べて、どちらが良いか判断してみよう。
    いきなり書くのが難しかったら、以下の補題をやってみるとよい。
    補題1
    商品番号を渡すと、1個あたりの金額を計算する関数を書いてみよう。
    補題2
    商品番号を複数渡すと、個数1個として金額を合計する関数を書いてみよう。

    View Slide

  102. スーパーの支払金額
    お題2 消費税
    商品リストの金額は外税なので、合計金額に消費税8%を足して、支払金額を返すようにしよ
    う。
    お題3 タバコの消費税
    タバコの価格には消費税が含まれているので(内税)、消費税の計算からタバコは除かないと
    いけない。

    View Slide

  103. スーパーの支払金額
    お題4 割引
    リンゴは1個100円だが、3つ買うと280円になる。
    お題5 おまけ
    なんでも、同じものを10個買うと、1個おまけでもらえる。11個で10個ぶんの金額(12個で11
    個分、20個で19個分、22個で20個分、...)という形で実現しよう。

    View Slide

  104. スーパーの支払金額
    お題6 おまけのライター
    タバコを1カートン(10個)買うと、ライターがおまけでもらえる。引数にライターがあったら無料
    になるというふうに実現しよう。
    お題7 お弁当
    弁当類と飲み物(お茶とコーヒー)をいっしょに買うと、20円引きになる。

    View Slide

  105. スーパーの支払金額
    お題8 サービスしすぎない
    お題4~7のようなサービスは、同じ商品については重複しない。一番安くなるものをひとつだ
    け適用する。
    お題9 タイムセール
    お弁当は20時を過ぎると半額になる。
    お題10 タイムセールとサービス
    お弁当のタイムセールは、他のサービスと重複してよい。

    View Slide

  106. スーパーの支払金額
    お題11 コンフィグレーション
    以上のようなサービス内容を、プログラムと別の設定ファイルなどで自由に変更できるように
    したい。

    View Slide

  107. 本日のお題
    整数の区間
    http://bit.ly/1hAoTeG

    View Slide

  108. 本日のお題
    DFG(大富豪の手判定)
    https://is.gd/RIC2HW

    View Slide

  109. 本日のお題
    セマンティック・バージョニング
    https://is.gd/YT5tN0

    View Slide