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

python-tdd

 python-tdd

みんなのPython勉強会#37 の資料

https://startpython.connpass.com/event/81625/presentation/

378406b82e2c225bdc1a76c9a886f955?s=128

eiji.ienaga

July 11, 2018
Tweet

Transcript

  1. 「テスト駆動開発」を通じて プログラマが コードと向き合う活動を 改めて学び直す おーい磯野〜♪ 多国通貨を写経しようぜ みんなのPython勉強会#37 家永英治

  2. ⾃⼰紹介 • 家永英治 • Tiwtter: @haru01 • 永和システムマネジメント • アジャイルコーチ

    • Scrumに限らず ユニットテスト リファクタリング TDD …の良さもお伝えしたい︕ • ときどき仕事や趣味でプログラマ • 実務はJavaが⼤半、Rubyが少々。 Pythonは趣味、最近はGoを勉強中 • ブログ︓https://twop.agile.esm.co.jp/ 2
  3. 3 https://agile.esm.co.jp/

  4. 今⽇の発表の⽬標: 書籍の多国通貨を お家で練習したくなる 4

  5. ケントベックはTDDを使って プログラマのどんな フラストレーション を解消したかったんだろうか︖ 5

  6. ⽬標 「動作するきれいなコード」 動作するきれいなコードで得たいものは。。。。 6

  7. 動作するきれいなコードを使って プログラマが実現したいこと ✔ プログラミング活動を制御可能にしたい • 分析⿇痺で設計はきれいだが動かないで四苦⼋苦はヤダ • テスト⼯程という名のデバック地獄で、遅れて⽋陥の対応に追われる⽇々はヤダ • はじめから予期しない事が起こる複雑さがあるが、不安で押しつぶされるのはヤダ

    ✔ コードを通じてチームメイトと信頼関係を築きたい • 動作しないコードを渡されてるのはヤダ・渡すのはヤダ • 不吉な臭いがするコードを渡されるのはヤダ・渡すのはヤダ ✔ 作ったものでユーザに快適さを届けたい • いつまでたっても壊れた動かないソフトウェアで、顧客やユーザをイライラさせるのはヤダ ✔ 気持ちよくコードを書き続けたい • 半年後、⼀年後に不吉な匂いがするコードに囲まれて、⽬の輝きを失ってしまうはヤダ 7
  8. But 8

  9. A) あとから デバック地獄 9

  10. “JUnitなどの⾃動テストの仕組みに出会うまでは、テストは⼿と⽬でやっていまし た。それがすごく⾯倒で⼼理的に負担だったので、テストは好きではありません でした。 若い頃は「⾃分が書いたコードにはバグがない」と⾃信過剰でした。しかし、実 際にプログラムを動かしてみると、全然動かない、あるいはバグだらけ。⾃分に 失望を感じ、それが痛みになっていました。 “⾃分のコードを嫌いにならない、そのためにやるべきこと” 和⽥卓⼈⽒ http://tech.nikkeibp.co.jp/atcl/nxt/column/18/00240/060600009/?P=6 10

  11. 3.プレシャー UP 1.⼿と⽬のテスト が⼿間で確認頻度 DOWN 2.意図せず ⽋陥混⼊UP あとでまとめて⾒つけた ⽋陥の対応に 追われて。。。

    時間に追われて テストする 時間がなく。。。 11 プログラマは⽋陥対応に追われ コントロールを失い⾃信を喪失 ⼿と⽬に頼るため ⼼理的に負担のある作業 ※ 付録A、25章を参考にいろいろ追記
  12. ⽋陥数 時間 ※ イメージ図 12 ? 後でまとめて発覚 テスト未実施で ステータス不明 ௚͢ͷʹ

    ࢛ۤീۤ
  13. 「俺の環境では動い たよ」 ソフトウェアが壊れるだけでなく チームメイトや顧客との信頼関係も壊れてしまう 13

  14. B)技術的負債の増⼤ 14

  15. プレッシャー UP ⼿と⽬によるテストで 実施頻度DOWN ⽋陥数 UP 技術的負債 UP 怖くて リファクタリング出来ず

    頻度DOWN 障害対応や要望 対応にてまどり。。 15 ※テスト熱中症、技術的負債を参考に記載
  16. ٕज़తෛ࠴ ˺௥Ճमਖ਼ͷਏ͞ ˺มߋίετ ࣌ؒ ※ イメージ図 16

  17. 重複や⻑過ぎるメソッド で頭痛 あとで修正の影響範囲調査でこまる。 ヌケモレが発⽣しがち 17

  18. どうやって ⼆重の悪循環から 抜け出す︖ 18

  19. ⼿と⽬のテストの箇所が レバレッジポイントでは︖ 詳しくは25章を参照 19

  20. ⼿と⽬のテストの作業を コード化し機械にやってもらおう ⼈には不可だが、機械なら1⽇に100回、300回とテスト実施可能 20

  21. テスト駆動開発の基本3ステップ • Red︓テストを⼩さく1つ書く。動作しない。 • Green︓テストをパスさせる。べた書きや、コピペなど⼤罪を 犯しても良い。 • Refactor: 重複を取り除く。 上をこまめに頻繁に繰り返す

    21
  22. 3.プレッシャー UP 1.⼿と⽬によるテストで 実施頻度DOWN 2.1.⽋陥数 UP 2.2.2.技術的負債 UP 2.2.1.怖くて リファクタリング出来ず

    頻度DOWN 障害対応や要望 対応にてまどり。。 意図せず ⽋陥を埋め込んで。。。 22
  23. 4.プレッシャー Down 2.機械によるテストで で実施頻度UP 2.1.⽋陥数 Down 3.2.2.技術的負債 DOWN 3-2-1.安⼼して リファクタリング

    頻度UP 障害対応や要望 対応がスムーズになり 23 1.こまめにテスト (仕様の具体例) をコード化UP 早期に発⾒して対応できるので。。
  24. 保存すれば即テスト実⾏の 環境の中でコードを書くデモ 例えば jest --watch 24

  25. 修正で 壊れていないか確認する時間 を減らしていこう ⼿と⽬のテストを頻繁に実施するは⾟い 経済的な時間的コストのほか、プログラマとしてのペインの時間を減らす 25

  26. コードを読んで理解するまでの時間 を減らしていこう 不吉な臭いがするコードを読むのは⾟い。 経済的な時間的コストのほか、プログラマとしてのペインの時間を減らす 26

  27. プログラマが Happyにプログラミング する時間を増やしていこう 技術的負債に悩まずに、軽やかに&健やかにプログラミングする時間を増やそう 27

  28. ユーザが Happyに過ごす時間 を増やしていこう コードがリポジトリーに眠ったままでは、顧客やユーザには嬉しさが届かない 本当に欲しかったものが何かの学びも得られない 動くソフトウェアをタイムリーにリリースしていこう 28

  29. ⽋陥数 時間 ⽋陥数 時間 ※ イメージグラフ 29 ?

  30. 技術的負債 ≒追加修正の⾟さ ≒変更コスト 時間 時間 ※ イメージグラフ 30 技術的負債 ≒追加修正の⾟さ

    ≒変更コスト
  31. 注意︓ TDDはテスト技法ではない︕ とWard Cunninghamが⾔っていた 31

  32. “テスト︓ ⾃動化され、具体化された、明確なテスト。ボタンを押せば⾛り出す。 ⽪⾁なことに、TDDはテスト技法ではない(Cunninghamの公案)。 TDDは分析技法であり、設計技法であり、実際には開発のすべてのア クティビティを構造化する技法なのだ。” KentBeck. テスト駆動開発 32

  33. “開発︓ ソフトウェア開発における伝統的な「フェーズ主義」の⾵潮が弱 まったのは、時間が離れると設計判断のフィードバックが難しく なるからだ。開発は分析、論理設計、物理設計、実装、テスト、 レビュー、結合、デプロイを伴う複雑なダンスに変わった。” KentBeck. テスト駆動開発 33

  34. Spec Design Impl Testとい名は付いているが 実態はデバック地獄 時間 時間 事前計画、事前設計を重視でプログラミング フィードバックを重視で、テスト−仕様、実装、設計のダンス 34

    AHA! AHA! Oh my gosh! AHA! AHA! AHA!
  35. "テスト駆動開発は、プログラミング中の不安をコントロールす る⼿法だ。ここでは「不安」を悪い意味で使っているのではない (我々は⾚ちゃんではないからね)。「これは困難な問題なので、 最初からすべてを⾒通せるわけではない」という真っ当な感覚の ことだ。" KentBeck. テスト駆動開発 35

  36. TDDを学ぶには︖ 36

  37. 1写経する 練習、練習、練習 や CODE KATA スポーツ選⼿がくり返し練習するように プログラマもプログラミングを練習する 37

  38. TDDの定番の練習お題 • 書籍I部︓多国通貨 • 書籍II部︓テスティングフレームワーク • FizzBuzz • ボーリングゲーム •

    ⾃動販売機 • 整数の閉区間 • セマンティック・バージョニング • ライフゲーム • Etc… http://devtesting.jp/tddbc/ http://d.hatena.ne.jp/absj31/20120721/1342880403 http://cyber-dojo.org/ http://codingdojo.org/KataCatalogue/ (探せば、練習お題がいくつかある。) 38
  39. お⼿本を⾒るには︖ • 和⽥さんのFizzBuzzお題でのTDDライブ • https://channel9.msdn.com/Events/de-code/2017/DO03 • Robert-c-martinによる TDD ボーリングゲームのKATAの ステップバイステップでつくる様⼦

    • https://www.slideshare.net/lalitkale/bowling-game-kata-by- robert-c-martin (Youtubeを探せばTDDをやっている様⼦の動画がいくつか⾒つかる) 39
  40. "本書『テスト駆動開発』の第I部、第II部が特殊な書き⽅を されているのは、この「過程」を読者に追体験してもらうた めです。テスト駆動開発の本質をつかむためには、まとまっ た量の、⼿を動かしながら学べる良質なチュートリアルが必 要なのです。" KentBeck. テスト駆動開発 付録C 40

  41. 2TDDのパターンを知る TDDのコツがパターンで整理されている 41

  42. テスト駆動開発のパターン テスト(名詞) 独⽴したテスト TODOリスト テストファースト アサートファースト テストデータ 明⽰的なデータ レッドバーのパターン ⼀歩を⽰すテスト

    はじめのテスト 説明的なテスト 学習⽤テスト 脱線はTODOリストへ 回帰テスト 休憩 やり直す 安い机に良い椅⼦ テスティングのパターン ⼩さいテスト Mock Object(擬装オブジェクト) Self Shunt(⾃⼰接続) Log String(記録⽤⽂字列) Crash Test Dummy(衝突実験ダミー⼈形) 失敗させたままのテスト きれいなチェックイン グリーンバーのパターン 仮実装を経て本実装へ 三⾓測量 明⽩な実装 ⼀から多へ xUnitのパターン アサーション フィクスチャー 外部フィクスチャー テストメソッド 例外のテスト まとめてテスト デザインパターン Command Value Object Null Object Template Method Pluggable Object Pluggable Selector Factory Method Imposter Composite Collecting Parameter Singleton リファクタリング 差異をなくす 変更の分離 データ構造の変更 メソッドの抽出 メソッドのインライン化 インタフェースの抽出 メソッドの移動 メソッドオブジェクト パラメータの追加 メソッドからコンストラクタへ のパラメータの移動 42 3部の パターン一覧
  43. TDDの 定番パターン 43

  44. TODOリスト 44

  45. 脱線はTODOリストへ 45

  46. テスト(名詞) 46

  47. テストファースト 47

  48. アサートファースト 48

  49. 説明的なテスト 49

  50. ⼩さいテスト 50

  51. 仮実装を経て 本実装へ 51

  52. 明⽩な実装 52

  53. 三⾓測量 53

  54. 差異をなくす 54

  55. きれいなチェックイン 55

  56. 休憩 56

  57. やり直す 57

  58. Design => Designing 不確実性がある前提で、初期に1回設計して終わりではなく、 反復のなかで予期せぬことから学びを得て、 ちょっとずつコードや設計を修復し続ける 有機的な設計、進化的設計 58

  59. 「インタフェースが使いづら いか︖」 メソッドネーミングがドメイン⽤語からかけ離れすぎている︖ 引数が多すぎる︖ コマンドとクエリが混ざっている︖ 副作⽤あり︖ 60

  60. 「テストが書きにくいか︖」 蜜結合では︖ 複数の責務をもっていないか︖ 61

  61. 「新たな機能追加が難しい か︖」 「追加が難しい」は、リファクタリングすべきのサインの⼀つ 62

  62. 「コードに読んで 不快に感じたか︖」 リファクタリングの「不吉な臭い」を参考に。 家をお掃除し続けるように、 コードもお掃除し続けなければ、散らかり不快な環境になる 63

  63. 実は TDDにもデザインパターンが 出てきます TDDは設計技法でもあるからね 65

  64. テスト駆動開発のパターン テスト(名詞) 独⽴したテスト TODOリスト テストファースト アサートファースト テストデータ 明⽰的なデータ レッドバーのパターン ⼀歩を⽰すテスト

    はじめのテスト 説明的なテスト 学習⽤テスト 脱線はTODOリストへ 回帰テスト 休憩 やり直す 安い机に良い椅⼦ テスティングのパターン ⼩さいテスト Mock Object(擬装オブジェクト) Self Shunt(⾃⼰接続) Log String(記録⽤⽂字列) Crash Test Dummy(衝突実験ダミー⼈形) 失敗させたままのテスト きれいなチェックイン グリーンバーのパターン 仮実装を経て本実装へ 三⾓測量 明⽩な実装 ⼀から多へ xUnitのパターン アサーション フィクスチャー 外部フィクスチャー テストメソッド 例外のテスト まとめてテスト デザインパターン Command Value Object Null Object Template Method Pluggable Object Pluggable Selector Factory Method Imposter Composite Collecting Parameter Singleton リファクタリング 差異をなくす 変更の分離 データ構造の変更 メソッドの抽出 メソッドのインライン化 インタフェースの抽出 メソッドの移動 メソッドオブジェクト パラメータの追加 メソッドからコンストラクタへ のパラメータの移動 66 3部の パターン一覧
  65. Red Green Refactor の試⾏錯誤のなかで 67

  66. 必要があれば、 デザインパターンを取り込む 68

  67. 不要であれば 取り込まない、取り外す KISS︓Keep it simple, stupid 69

  68. https://twop.agile.esm.co.jp/tdd-and-incremental-design-with-patterns-c20179dffbea 70

  69. 詳しくは3部 71

  70. 写経 72

  71. I部のお題は多国通貨 サンプルコードはJavaだけど、Pythonで練習すれば問題ない 73

  72. 書籍の2章までの 雰囲気をスライドでお届け 74

  73. 1章 仮実装を経て 本実装へ とてもベイビーステップでものづくりします 75

  74. どこに向かって作業すれば︖ どこから始めよう︖ 76

  75. パターン︓TODOリスト 何をテストすべきだろうかーー着⼿する前に、必要になりそうなテストを リストに書き出しておこう 77

  76. TODO • $5 + 10CHF = $10 (レートが2:1の場合) • $5

    * 2 =$10 78
  77. いつからテストを始める︖ 79

  78. パターン︓テストファースト いつテストを書くべきだろうかーーそれはテスト対象のコードを書く前だ。 80

  79. [pylint] E0401:Unable to import 'dollar' 81 import pytest from dollar

    import Dollar def test_money_multiplication(): five = Dollar(5) five.times(2) assert 10 == five.amount
  80. エラーのほかに いろいろ問題があるコード 副作⽤ありのメソッド amountがpublic Etc.. 82

  81. だけど、TODOに積んで、 後まわし Red Green Refactor中に後からカイゼンしたい項⽬のほか テスト項⽬を発⾒してTODOに積むこともあるよ。 83

  82. パターン︓脱線はTODOリストへ 脇道のそれずに、(技術的な)疑問を検証するにはどうしたらよいだろう かーーもし脱線しそうなら、その疑問をTODOリストに加え、元の仕事に戻 ろう。 84

  83. TODO • $5 + 10CHF = $10 (レートが2:1の場合) • $5

    * 2 =$10 • amount を privateにする • Dollarの副作⽤ • Moneyの丸め処理どうする? 85
  84. 選択した 眼の前のタスクに集中 => $5 * 2 =$10 86

  85. 87 [pylint] E0401:Unable to import 'dollar' import pytest from dollar

    import Dollar def test_money_multiplication(): five = Dollar(5) five.times(2) assert 10 == five.amount
  86. E AttributeError: 'Dollar' object has no attribute 'amount' 88 class

    Dollar: def __init__(self, amount): pass def times(self, multiplier): pass import pytest from dollar import Dollar def test_money_multiplication(): five = Dollar(5) five.times(2) assert 10 == five.amount
  87. class Dollar: def __init__(self, amount): self.amount = 0 def times(self,

    multiplier): pass … E assert 10 == 0 E + where 0 = <dollar.Dollar object at 0x104177278>.amount 89 import pytest from dollar import Dollar def test_money_multiplication(): five = Dollar(5) five.times(2) assert 10 == five.amount
  88. 期待通りのRed 意図せずGreenならテストコードや実⾏⽅法にどこか間違いがあるかも︖ 90

  89. エラーメッセージや テスト失敗メッセージは プログラマを導く良きパートナー 機械に怒られているのではない。 機械に次の⼀歩を教えてもらっている テスト失敗メッセージが分かりづらいなら メッセージがわかりやすいように修正。 91

  90. よしGreenにするぞ︕ 速攻でGreenにするには︖ テストで解くべきExpectedとActualのギャップが明確になった状態 92

  91. パターン︓仮実装を経て本実装へ 失敗するテストを書いてから、最初に⾏う実装はどのようなものだろう かーーベタ書きの値を返そう。それでテストが通るようになったら、ベタ 書きの値をだんだん本物の式や変数に置き換えていく 93

  92. class Dollar: def __init__(self, amount): self.amount = 0 def times(self,

    multiplier): pass 94 import pytest from dollar import Dollar def test_money_multiplication(): five = Dollar(5) five.times(2) assert 10 == five.amount … E assert 10 == 0 E + where 0 = <dollar.Dollar object at 0x104177278>.amount
  93. class Dollar: def __init__(self, amount): self.amount = 10 def times(self,

    multiplier): pass 95 import pytest from dollar import Dollar def test_money_multiplication(): five = Dollar(5) five.times(2) assert 10 == five.amount
  94. やったー︕ 仮実装で意図せずRedになったら、もしかしたら テストコードやテスト実⾏の仕⽅に間違いがあるかも 96

  95. もちろん ベタ書きなので タスク完了とは⾔えない 97

  96. ここまでやったステップ • ⼩さいテストを1つ書く。 • すべてのテストを実⾏し、1つ失敗することを確認する。 • ⼩さい変更を⾏う。 • 再びテストを実⾏し、すべて成功することを確認する。 •リファクタリングを⾏い、重複を除去する。

    98
  97. リファクタリングで 本物の実装に近づく 99

  98. “つまり、TDDでは例えばベタ書きの値を変数に置き換える変更 であっても、胸を張ってそれを「リファクタリング」と呼べる。 なぜなら、通っているテストは変わらず通り続けるからだ。” KentBeck.テスト駆動開発 100

  99. class Dollar: def __init__(self, amount): self.amount = 10 def times(self,

    multiplier): pass 101 import pytest from dollar import Dollar def test_money_multiplication(): five = Dollar(5) five.times(2) assert 10 == five.amount
  100. class Dollar: def __init__(self, amount): self.amount = 5 * 2

    def times(self, multiplier): pass 102 import pytest from dollar import Dollar def test_money_multiplication(): five = Dollar(5) five.times(2) assert 10 == five.amount
  101. class Dollar: def __init__(self, amount): self.amount = amount * 2

    def times(self, multiplier): pass 103 import pytest from dollar import Dollar def test_money_multiplication(): five = Dollar(5) five.times(2) assert 10 == five.amount
  102. class Dollar: def __init__(self, amount): self.amount = amount def times(self,

    multiplier): self.amount = self.amount * 2 104 import pytest from dollar import Dollar def test_money_multiplication(): five = Dollar(5) five.times(2) assert 10 == five.amount
  103. class Dollar: def __init__(self, amount): self.amount = amount def times(self,

    multiplier): self.amount = self.amount * multiplier 105 import pytest from dollar import Dollar def test_money_multiplication(): five = Dollar(5) five.times(2) assert 10 == five.amount
  104. class Dollar: def __init__(self, amount): self.amount = amount def times(self,

    multiplier): self.amount *= multiplier 106 import pytest from dollar import Dollar def test_money_multiplication(): five = Dollar(5) five.times(2) assert 10 == five.amount
  105. やったー︕ 107

  106. Greenを保ちながら ベイビーステップで プログラミング 108

  107. TODO • $5 + 10CHF = $10 (レートが2:1の場合) • $5

    * 2 =$10 • amount を privateにする • Dollarの副作⽤ • Moneyの丸め処理どうする? 109
  108. 2章 明⽩な実装 Value Objectを使っての インタフェースの修復 110

  109. TODO • $5 + 10CHF = $10 (レートが2:1の場合) • $5

    * 2 =$10 • amount を privateにする • Dollarの副作⽤ • Moneyの丸め処理どうする? 111
  110. TODOに積んだ 副作⽤に取り組む 112

  111. これは無理が ある 副作⽤あり five は $10 に import pytest from

    dollar import Dollar def test_money_multiplication(): five = Dollar(5) five.times(2) assert 10 == five.amount five.times(3) assert 15 == five.amount 113
  112. 副作⽤ありの インタフェースの設計 に問題あり 114

  113. パターン︓Value Object 広く共有されるものの、同⼀インスタンスであることはさほど重要でない オブジェクトを設計するにはどうしたらよいだろうか――オブジェクト作 成時に状態を設定したら、その後決して変えないようにする。オブジェク トへの操作は必ず新しいオブジェクトを返すようにしよう。 115

  114. Value Objectパターン を取り込んで インタフェースを修復 116

  115. > assert 10 == product.amount E AttributeError: 'NoneType' object has

    no attribute 'amount' 117 import pytest from dollar import Dollar def test_money_multiplication(): five = Dollar(5) product = five.times(2) assert 10 == product.amount product = five.times(3) assert 15 == product.amount class Dollar: def __init__(self, amount): self.amount = amount def times(self, multiplier): self.amount *= multiplier
  116. インタフェースが変わって 失敗 timesメソッドは今は何もリターンしない。 118

  117. すぐにGreenにできるなら︖ 仮実装が不要なら︖ 119

  118. パターン︓明⽩な実装 シンプルな操作を実装するにはどうすればよいだだろうかーーそのまま実 装しよう。 120

  119. > assert 10 == product.amount E AttributeError: 'NoneType' object has

    no attribute 'amount' 121 import pytest from dollar import Dollar def test_money_multiplication(): five = Dollar(5) product = five.times(2) assert 10 == product.amount product = five.times(3) assert 15 == product.amount class Dollar: def __init__(self, amount): self.amount = amount def times(self, multiplier): self.amount *= multiplier
  120. 122 import pytest from dollar import Dollar def test_money_multiplication(): five

    = Dollar(5) product = five.times(2) assert 10 == product.amount product = five.times(3) assert 15 == product.amount class Dollar: def __init__(self, amount): self.amount = amount def times(self, multiplier): return Dollar(self.amount * multiplier)
  121. やったー︕ 123

  122. 仮実装を経て本実装へ と 明⽩な実装 124

  123. 2つの歩幅の調整を 上⼿く使い分ける 125

  124. すぐに解けるなら 「明⽩な実装」 126

  125. 道のりが⻑い場合 「仮実装を経て本実装へ」 10min以上Redが続いている場合、ステップ幅を⼩さく。 「明⽩な実装」の⽅針をやめて 「仮実装」に切り替え 道のりが⻑い場合は「⼩さいテスト」の別選択もある 127

  126. TODO • $5 + 10CHF = $10 (レートが2:1の場合) • $5

    * 2 =$10 • amount を privateにする • Dollarの副作⽤ • Moneyの丸め処理どうする? 129
  127. 2章完 130

  128. パターン︓やったー︕ テストが期待通りパスしたり、すっきりとリファクタリングできたり、タスクがドーンと完了した ら︖ーー ⼩さくてもうまく出来たことの成功を祝おう。まだまだ道のり⻑いが、勇気を持って歩み づづけるために。ペアプロやモブプロを実施している場合は、両⼿を上げるやフィスト・バンプやハ イタッチなど体を使って表現すると、喜びをより倍増できる。 (オリジナルにはない。書籍のフェアレスチェンジの「⼩さな成功」「ステップバイステップ」やペ アプログラミングやWEB+DBを参照) 131

  129. 3章以降は︖ 132

  130. 予告 133

  131. 3章 134

  132. 参上︕三⾓測量 仮実装、明⽩な実装と⽐較される3番⽬のキャラ 135

  133. 4章 136

  134. 説明的なテストで 意図を伝える テスト対象の仕様や意図が伝わるように書き直す テストコードは機械だけでなくチームメイトにも理解できるように書く 137

  135. 5章 138

  136. Kent Beck コピペの禁忌に⼿を出す DollarをコピペしてFranc作成 この先どうなっちゃう︖ 139

  137. 11章 140

  138. さらば 重複コード Dollar&Franc ついに消し去る。 141

  139. 6章からの重複の取 り除きの道のりには いったい何があった のか︖ 142

  140. 詳しくは 写経して のお楽しみ 143

  141. まとめ 144

  142. ケントベックはTDDを使って プログラマのどんな フラストレーション を解消したかったんだろうか︖ 145

  143. 動作するきれいなコードを使って プログラマが実現したいこと ✔ プログラミング活動を制御可能にしたい • 分析⿇痺で設計はきれいだが動かないで四苦⼋苦はヤダ • テスト⼯程という名のデバック地獄で、遅れて⽋陥の対応に追われる⽇々はヤダ • はじめから予期しない事が起こる複雑さがあるが、不安で押しつぶされるのはヤダ

    ✔ コードを通じてチームメイトと信頼関係を築きたい • 動作しないコードを渡されてるのはヤダ・渡すのはヤダ • 不吉な匂いがするコードを渡されるのはヤダ・渡すのはヤダ ✔ 作ったものでユーザに快適さを届けたい • いつまでたっても壊れた動かないソフトウェアで、顧客やユーザをイライラさせるのはヤダ ✔ 気持ちよくコードを書き続けたい • 半年後、⼀年後に不吉な匂いがするコードに囲まれて、⽬の輝きを失ってしまうはヤダ 146
  144. 3.プレッシャー UP 1.⼿と⽬によるテストで 実施頻度DOWN 2.1.⽋陥数 UP 2.2.2.技術的負債 UP 2.2.1.怖くて リファクタリング出来ず

    頻度DOWN 障害対応や要望 対応にてまどり。。 意図せず ⽋陥を埋め込んで。。。 147
  145. 4.プレッシャー Down 2.機械によるテストで で実施頻度UP 2.1.⽋陥数 Down 3.2.2.技術的負債 DOWN 3-2-1.安⼼して リファクタリング

    頻度UP 障害対応や要望 対応がスムーズになり 148 1.こまめにテスト (仕様の具体例) をコード化UP 早期に発⾒して対応できるので。。
  146. ⽋陥数 時間 ⽋陥数 時間 ※ イメージグラフ 149 ?

  147. 技術的負債 ≒追加修正の⾟さ ≒変更コスト 時間 時間 ※ イメージグラフ 150 技術的負債 ≒追加修正の⾟さ

    ≒変更コスト
  148. コードを読んで理解するまでの時間 を減らしていこう 不吉な臭いがするコードを読むのは⾟い。 経済的な時間的コストのほか、プログラマとしてのペインの時間を減らす 151

  149. 修正で 壊れていないか確認する時間 を減らしていこう ⼿と⽬のテストを頻繁に実施するは⾟い 経済的な時間的コストのほか、プログラマとしてのペインの時間を減らす 152

  150. プログラマが Happyにプログラミング する時間を増やしていこう 技術的負債に悩まずに、軽やかに&健やかにプログラミングする時間を増やそう 153

  151. ユーザが Happyに過ごす時間 を増やしていこう コードがリポジトリに眠ったままでは、顧客やユーザには嬉しさが届かない 本当に欲しかったものが何かの学びも得られない。 動くソフトウェアをタイムリーにリリースしていこう 154

  152. テスト駆動開発のパターン テスト(名詞) 独⽴したテスト TODOリスト テストファースト アサートファースト テストデータ 明⽰的なデータ レッドバーのパターン ⼀歩を⽰すテスト

    はじめのテスト 説明的なテスト 学習⽤テスト 脱線はTODOリストへ 回帰テスト 休憩 やり直す 安い机に良い椅⼦ テスティングのパターン ⼩さいテスト Mock Object(擬装オブジェクト) Self Shunt(⾃⼰接続) Log String(記録⽤⽂字列) Crash Test Dummy(衝突実験ダミー⼈形) 失敗させたままのテスト きれいなチェックイン グリーンバーのパターン 仮実装を経て本実装へ 三⾓測量 明⽩な実装 ⼀から多へ xUnitのパターン アサーション フィクスチャー 外部フィクスチャー テストメソッド 例外のテスト まとめてテスト デザインパターン Command Value Object Null Object Template Method Pluggable Object Pluggable Selector Factory Method Imposter Composite Collecting Parameter Singleton リファクタリング 差異をなくす 変更の分離 データ構造の変更 メソッドの抽出 メソッドのインライン化 インタフェースの抽出 メソッドの移動 メソッドオブジェクト パラメータの追加 メソッドからコンストラクタへ のパラメータの移動 155 3部の パターン一覧
  153. “テスト︓⾃動化され、具体化された、明確なテスト。ボタンを 押せば⾛り出す。⽪⾁なことに、TDDはテスト技法ではない (Cunninghamの公案)。TDDは分析技法であり、設計技法で あり、実際には開発のすべてのアクティビティを構造化する技法 なのだ。” 156

  154. TDDを学ぶには、 定番の多国通貨の 写経を複数回試すが おすすめ! 157