『テスト駆動開発』を理解するために写経した

# TL;DR
- 本書で写経を進めていたので、『テスト駆動開発』を理解するためになじみのある言語で写経したら、思った以上に腹落ちすることが多かった
- 個人的に思う『テスト駆動開発』の理解度を上げるステップは3つ
    - xUnit(第二部)と自身になじみのある言語のテスティングフレームワークを理解する
    - 第一部の多国通貨を実際に手を動かして作る
    - 第三部を定期的に読み返す

# はじめに
書籍って、その人の持っている知識量によって、理解度が変わるな、って個人的に思ってます。ある人には刺さって、ある人には刺さらない、この時の自分には刺さるけど、前の自分には刺さらない、とか、容易にあります。

また、どう読むかによって、読み直す回数によっても、理解度が変わります。

僕は、『テスト駆動開発』を1年前くらいはちゃんと理解できませんでしたが、今読んだ（写経した）ら思った以上に多くの部分を理解できた気がします。

そして改めて『テスト駆動開発』は良書と感じ、もっと良く理解するために必要だと個人的に考えたステップを紹介したい、と思います。


# 目次
- やったこと
    - 0.テストを書けるようにする
    - 1.多国通貨を作る
    - 2.小さい機能でテスト駆動開発を実践する
    - 3.定期的に第三部を読み返す
- 写経の振り返り
    - 良かったこと
    - 感じたこと

# やったこと
## 0. テストを書けるようにする

このステップは、全くテストを書いたことがない人だけ取り組むのが良いです。

本書にも

> TDDはテスト技法ではない。TDDは分析技法であり、設計技法であり、実際には開発のすべてのアクティビティを構造化する技法なのだ

とあるように、テスト駆動開発は、テスト技法ではないです。プログラミングのスキルです。テスト駆動開発におけるテストコードはあくまで副産物であり、目的は**動作するきれいなコードを書く**、です

そのため、テスト駆動開発をする前に、すんなりテストコードを書ける、という状態を作る必要があります。

- 第二部のxUnitで、テスティングフレームワークは何ができるかを理解する
- 自身になじみのある言語のテスティングフレームワークを使ってテストコードを書けるようになる

**第二部のxUnitで、テスティングフレームワークは何ができるかを理解する**
このフェーズでは、写経はまだ行いません。まずはxUnitとはどういったものか、xUnitで何ができるか、を理解している、というのが、前提にあると感じました（もし本書にも書いていたら見逃してしまいました）。

ウィキペディアの [xUnitの設計](https://ja.wikipedia.org/wiki/XUnit#xUnit%E3%81%AE%E8%A8%AD%E8%A8%88) の説明もとてもシンプルで個人的に好きです。本書の第二部のまとめを読むなどして、概念をざっとつかみます。


**自身になじみのある言語のテスティングフレームワークを使ってテストコードを書けるようになる**
次に、テストを書けるようになる必要があります。
本書では、写経をお薦めしていて、実際にその通りにするのが一番です。テスト駆動開発の過程を学ぶ、というのが、写経の目的です。

僕個人は

- Javaに触れたことがなく、なじみのない言語でテスト駆動開発を学ぶ、というのがなんとなく理解度を落としそう
- TypeScriptだったらこうだな、、とか考えながら実装するのが楽しそう

という二つの理由から、写経を書き慣れているTypeScript + Jestで進めました。

ただ手のひらを返すようで申し訳ないですが、どっちでも良いと思ってます。僕自身はTypeScript書き慣れているし、Jestのセットアップも何度もやっているので、TypeScriptで写経を進めました。


## 1. 多国通貨を作る
ここではただひたすらなぞります。
自分の中で

- ちゃんと黙読する
- 1章ごとにPRを出す
- やったこと・感じたことをPRに載せる

という三つのルールを立てて、開発していきました。

「ちゃんと黙読する」はちょっと馬鹿っぽいですが、わりと一番おすすめです。思考体験をなぞる、をそのまま実行できます。
現に、リファクタリングではないときに、テストコードを変更する前にプロダクトコードを変更しようとした時、「おっと危ない、、」と心の中で自然と漏れ出るようになりました。
黙読では足りない、という方は音読でも良いと思います。

残り二つのルールは、アウトプットの過程を残し、振り返れるようにするためです。

実際に僕が写経したリポジトリが貼っておきます↓

https://github.com/moroball14/tdd-with-typescript

## 2. 小さい機能でテスト駆動開発を実践する
業務で開発するプロダクトでも、個人アプリでも、実践に移すことで、より理解度が高まります。

とはいえ、まだちゃんと理解していないしな、、と不安になると思う（実際僕はなった）ので、できる限り小さい機能から始めるのがおすすめです。

実際、最初は小さいと思っていても大きい機能に発展する可能性はあります。そんな時、テスト駆動で開発していたら、副産物として出来上がったテストコードが、より良い設計を試す勇気を与えてくれます。第12章にある

- TDDはひらめきが正しい瞬間に訪れる保証するものではない
- 自信を与えてくれるテストときちんと手入れされたコードはひらめきへの備えになる
- ひらめいた時にそれを具現化するための備えでもある

という言葉は、本書で最も好きな言葉です。

## 3. 定期的に第三部を読み返す


定期的に読み返すことで、記憶への定着や、新しい気づきがあるといいます。

https://shuchi.php.co.jp/the21/detail/8195

実際に、『テスト駆動開発』を一度読んだことありましたが、第26章の「レッドバーのパターン」に書いてあった説明的なテスト、には、本当に最近悩んでいる事柄に対して、一つの解を提示してもらいました。

https://twitter.com/334ckAo7tevDizT/status/1616696522112126976?s=20&t=dkxP8DMnqbMyh1Gef810Ow

もちろん上記で挙げたのはほんの一部ですが、少しでも気づきを得られるため、一日一章ないしは一節は読んで良いかなって思います。

# 写経の振り返り
## 良かったこと
**TDDのサイクルを体に叩き込むことができた**
一番はやはり、追体験することで得られるTDDの思考プロセスを体で覚えることができたことです。
テストコードを先に修正する癖がついたことで、小さく失敗する、というサイクルを速く回せるようになりました。


**新しい知識が身についた**
テスト駆動開発、の思考プロセスを学ぶ上で、並行して周辺知識の学びもありました。
学習用テスト、と名付けられた手法は、どういった挙動をするのかを確かめるための自動テストです。ある関数の挙動を確かめるために、いちいち画面に反映されるのを待たなくても、テストで確認しちゃうのが速いです。詳しくは以下がご参考ください。

https://gihyo.jp/dev/serial/01/savanna-letter/0001

また、TypeScriptのMap.prototype.getの挙動を正しく理解することができました。これは、自身のなじみのある言語で写経した恩恵ですね。

https://qiita.com/mball/items/eba0c49b65856ae8ccf9

## 感じたこと
写経していく上で、

- 不吉な匂いのするコードを感じ取れる嗅覚が必要
- 綺麗なコードを書くための知識や経験が必要
- 意味のあるテストコードを書く能力が必要

と感じました。

写経していく中で、割と「不吉な匂いがする」って表現があった気がします。自然と使っていたので、前提として不吉なの匂いがするコードを感じ取れる嗅覚が必要かなって思いました。ここに関しては、ミノ駆動本と呼ばれる『良いコード／悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方』を読むと一定良さそうだなって感じます。

https://gihyo.jp/book/2022/978-4-297-12783-1

また、不吉な匂いを感じ取っても、綺麗なコードを書けなければ、効果はないです。この辺りはClean Architectureやデザインパターン、DDDなどの知識をインプットして活用できるようになるのが、良さそうだなって思いました。自分もまだまだ理解が浅いので、今後はこの辺りの知識もつけていきます。
何を学べば良いかわからない、とならないように第三部にもトピックがいくつかあるので参考にしてみてください。

最後は少しテストコードよりの話になります。テスト駆動開発を行うには、そもそもテストコードを書ける必要がある、と先述しました。意味のあるテストコードを書けるようになるには、一定学びや経験が必要です。『ソフトウェア品質を高める開発者テスト 改訂版 アジャイル時代の実践的・効率的でスムーズなテストのやり方』が個人的に支えになると思います。

https://www.shoeisha.co.jp/book/detail/9784798176390

# 終わりに
305ページに

> 読んだだけでは、深い得心には至らないでしょう

と書いてある通り、読んだだけでは理解できませんでした。ただ、写経して追体験することで、読んだだけの時とは比べ物にならないくらい、得たものがありました。

> TDDは結果ではなく過程に本質がある

ので、写経、おすすめです。