Slide 1

Slide 1 text

TDD実践を経て 変わったこと

Slide 2

Slide 2 text

私たち 鈴木 謙士 ・2015/07にユーザベースにJoin ・SPEEDA開発を中心に活動するソフトウェアエン ジニア ・猫とカレーが好き 橘内 孝幸 ・2015/08にユーザベースにJoin ・SPEEDA開発を中心に活動するソフトウェアエン ジニア ・DDDとGoが好き

Slide 3

Slide 3 text

今日お話すること 1. TDDのゴール 2. 設計・実装における変化 3. テスト・実装に対する価値観、行動の変化 4. プログラミング以外の変化

Slide 4

Slide 4 text

TDDのゴール

Slide 5

Slide 5 text

「動作するきれいなコード」

Slide 6

Slide 6 text

設計・実装における変化

Slide 7

Slide 7 text

設計の良し悪しの指標が変化 Before 1. 設計に対する良し悪しの判断が自己満足の域を出なかった 2. 悪い設計に気付くことなく、未来の誰かが損をしていた (過去の自分を殴りたい・・・) After 自分が書いたコードが良い設計なのか悪い設計なのか判断するとき、テスタビリティ (テスト容易 性)という指標が生まれた

Slide 8

Slide 8 text

テスタビリティが何故指標として役立つのか 1. テスタビリティが低い場合、様々な課題があることに気付いた a. 独立性が低い b. 密結合になりやすい c. 責務がバラけがち 2. 設計を議論する時に、テスタビリティの観点で話すことが出来る 3. テストがやり難いと感じたとき、設計を見直すことのできるチャンスだと捉えることができる

Slide 9

Slide 9 text

しくじりに「気づく」タイミングの変化 Before 書いたコードが実際使われる段階になってはじめてしくじっていることに気づく 完璧だな 実装するぞ しくじった…

Slide 10

Slide 10 text

しくじりに「気づく」タイミングの変化 様々なしくじり 1. 必要がなかった 1.1. 「今」必要ない 1.2. 未来永劫必要ない 2. そもそも使えない 2.1. 期待値に誤りがある 2.2. 他の部分と組み合わせられない 3. 使えるが、使いづらい

Slide 11

Slide 11 text

しくじりに「気づく」タイミングの変化 After テストを書いている段階でしくじりに気づく テスト書くぞ なんかおかしいぞ このコード、 ダメダメなのでは ・・・・・・

Slide 12

Slide 12 text

しくじりに「気づく」タイミングの変化 なぜテストを書いている段階で気づけるのか 1. 外側(実際に使う側)から内側に向かってテスト →実装を繰り返していくため、気づく気づか ない以前にそもそも使わないコードは生み出されづらい 2. 最初に期待値を考えてテストを書くことにより、期待値がコードレベルで明確になっている ため、使う段階になって期待と異なるということがない。 また、組み合わせ部分も先にテストに書くため、あとになって実は組み合わせられないとい うことがないし、先に気付くことができる 3. テスト自体がテストの書きづらさによって「設計が良くない」ことを教えてくれる

Slide 13

Slide 13 text

しくじりに「気づく」タイミングの変化 まとめ 以前は「想像」で実装を行い、その想像にあわせて想像通り動くテストを書いていたと言える。 想像が現実と一致していることもあったが、常にそうではなかった。 TDDは想像と現実のギャップを迅速に埋めてくれた。

Slide 14

Slide 14 text

実装の仕方の変化 Before はじめから完成形を目指した実装をしていた。 実装が完全に終わってから、その実装を検証するようなテストを書いていた。 とりあえず実装する ぞ。それも全部だ! 実装できたから テスト書こう

Slide 15

Slide 15 text

実装の仕方の変化 テストは、実装が正しいことを検証するためのみ に存在していた。 後でテスト書くため、テストが実装に依存する。 結果として次のようなことが起きていた。 1. テスト自体が複雑になっていた 「検証のためだから許容しよう」と考えてしまっていた。 2. 余計な検証をしていた 例: 一つのテストケースにアサートが複数あり、一緒くたに様々な検証をしている。 3. 必要以上に実装してしまっていた なんとなく実装するとやってしまいがち。 (YAGNIはどこいったの?) なんとなく野菜を買ったけど、 こんなにいらなかった・・・

Slide 16

Slide 16 text

実装の仕方の変化 他に考えられる問題 先に実装すると、検証しづらく怪しさを感じたとしても、これまでにかけたコストを無駄にしたくない という心理が働き、実装・設計を見直そうという意識になりづらい。 そのため、テストを通すためにトリッキーな方法をとったり、複雑性を許容してしまう。 また検証自体を目的とする場合、テストが独立していないことや過剰であることに気づきづらくな る。 なぜか実装コードが汚いは許せなくてもテストコードが汚いのは許容できてしまってたりする。

Slide 17

Slide 17 text

実装の仕方の変化 After まず仕様を考え、最小限度のテスト書き、その後実装。 必要があれば別のパターンのテストを書き、実装。徐々に育てていく。 小さくテストを書こう まずは仕 様と意図 を明確にし よう 実装するか

Slide 18

Slide 18 text

実装の仕方の変化 Q: なぜAfterになった? A: テスト・実装ともに改善できたから テストから先に書くことにより、仕様を考えたり、期待値を考えたり、検証内容を考えることに集中 できる。 テストから書き始めた場合、テストは実装に依存していない状態なので、怪しい匂いを感じた時点 で対処できる。 それは結果として設計や実装の改善に繋がった。 (テストを書くことで設計も行っている)

Slide 19

Slide 19 text

実装の仕方の変化 課題の解決法の例 1. アサートファースト アサートから書くと以下のようにシンプルに分けて考えられるようになる。 1.1. 期待値を明確にすることを考える(というかせざるを得ない)。 1.2. どう検証すべきかを考える。 2. テストの独立性を保つ 例えばアサートを一つにする。すると自然と検証内容もシンプルになる。 3. 最初はシンプルな1パターンのみ考える。(複数パターンの検証が考えられる場合) こうすると、実装の際はシンプルな一つの仕様を満たすことだけを考えればよく、実装も最 初は最小限度となる。更に自然とテストもアサートが 1つになっていく。

Slide 20

Slide 20 text

テスト・実装に対する 価値観、行動の変化

Slide 21

Slide 21 text

テストコードに対する価値観の変化 Before ・「実装したコードが100%で意図した通りに正しく動くならば テストコードがいらないのでは?」 ・「実装コードと、そのテストがあればいいよね」 After 1. テスト→実装→テストのサイクルだと、実装はテストをグリーンにするために存在 2. テストは、実装内容についてだけでなく、仕様 (要件)を満たしているかの確認のために存在 3. 意図しないグリーンなテストは実装が間違ってしまっている可能性もある テストの地位が明らかに上がった

Slide 22

Slide 22 text

ちょっとしたコードの書き方の変化 Before 個人で新しい言語を勉強しているとき、こんな書き方できるかなみたいな確認をするとき、実装か ら始めていた。 After 上記のようなケースでも、まず検証するコード(当然落ちる)から書くようになった。 なぜAfterになったか どういうことをさせたい、どうなっていてほしいのか、どう使えると嬉しいのかをコード上で明確にし てからの方がやりやすいと感じるようになったため。

Slide 23

Slide 23 text

プログラミング以外の変化

Slide 24

Slide 24 text

仕事の進め方の変化 Before すべてやりきるところまで一気に進めていた。失敗には最後になってから気づいていた。 After 全体のゴールは考えつつ、小さなゴールを定めて進めることが多くなった。 プロジェクトでも、小さく一つだけ実施してフィードバックを得て、徐々に育てるようになった。 なぜAfterになったか 大概のことは想定通り進まず、実際にやってみるまで不確定な要素が多い。 そういう場合では、フィードバックループは早い方がいいことが多いと考えるようになったため。

Slide 25

Slide 25 text

仕事の進め方の変化 つまり考え方は応用がきく TDDの 「迅速にフィードバックを得て、その結果を活かすことを繰り返す」 という考え方は、プログラミング以外に対しても効果を発揮する。 (シンプルに考えるという部分も)

Slide 26

Slide 26 text

仕事の進め方の変化 そもそもフィードバックは XPの5つの価値の1つであり、他の概念とも関連しているので、それぞ れにフィードバックがどう関わっているのかというのも興味深いトピックだと思う。 XP 「XPチームはできるだけ早く、できるだけ多くのフィードバックを生み出そうとする。 フィードバック のサイクルを数週間や数か月ではなく、 数分や数時間に短縮しようとする。フィードバック が 早く 手に入れば、 その分だけ早く適応できる。」 - エクストリームプログラミング (Kent Beck) -

Slide 27

Slide 27 text

仕事の進め方の変化 CI 「CIの中心的な原則の一つは、インテグレーションを「早めに」、かつ「頻繁に」行うこと」 「迅速なフィードバックにより、いち早く軌道を修正して変化に適応するための時間がもたらされ る」 - 継続的インテグレーション入門 (Paul Duvall) -

Slide 28

Slide 28 text

仕事の進め方の変化 CD 「フィーチャやバグフィックスがユーザーにとって役に立つかは、実際ユーザーの手に渡るまでは 推測に過ぎない。 (中略) したがってサイクルタイムを最小化し、効果的なフィードバックを構築できるようにすることがきわ めて重要。」 - 継続的デリバリー (Jez Humble, David Farley) -

Slide 29

Slide 29 text

心にゆとりを持ち、自信に繋がる Before 自分のコードが、不具合を引き起こしていないか不安になり動作確認をたくさんしてしまってい た。 After 1. デプロイされるものは、テストされたものである前提が生まれる。 圧倒的安心感! 2. 逆にテストがないと、どんなに正しいコードでも不安になる!

Slide 30

Slide 30 text

TDDの実践を経て(まとめ) ● 設計・実装・テストに対する価値観が変わった ● 仕事においての考え方にも影響をもたらした

Slide 31

Slide 31 text

書籍の紹介 テスト駆動開発 Kent Beck(著), 和田 卓人(翻訳) 実践テスト駆動開発 - テストに導かれてオブジェクト指向ソフトウェアを育てる - Steve Freeman (著), Nat Pryce (著), 和智 右桂 (翻訳), 高木 正弘(翻訳)

Slide 32

Slide 32 text

Thank you for Listen!