Tsubatoの発信記録

主に機械学習やデータサイエンス関連で学んだことを書いています。

読書記録 テスト駆動開発

0. この投稿の概要

  • 今更ながら「テスト駆動開発」を読んだので、今後の自分の開発にどうやって活かそうか考えたことをまとめます。

  • 本書は3章立てで、1章でJavaで多国通貨を足し合わせるプログラムをTDDで実装していき、2章はPythonでテストツール(xUnit)をTDDで実装、3章はTDDのパターンの解説です。自分は2章を写経しました。

1. 学んだこと, 考えたこと

テスト駆動開発をどう取り入れるか

  • テスト駆動開発によるプログラミングの作業は以下の3フェーズからなる。
    • レッド: 動作しない、コンパイルすら通らないかもしれないテストを1つ書く。
    • グリーン: そのテストを迅速に動作させる。この時、コードに期待値をベタ書きしたり類似する関数をコピペするような罪を犯すことを厭わない。
    • リファクタリング: テストを通すために発生した重複をすべて除去する。一般化する。
  • 一方で普段の自分の作業順は以下の通り。個人的に一番楽しいのは最後に修正とテストを繰り返しているフェーズ*1。TDDはこのフェーズを繰り返すことで開発を進めるようなものなので、うまく出来たら楽しい時間で埋め尽くせるか?
    • まず実装する。この時点で必要な一般化も考慮している。
    • テストを作る。大体最初から複数のテストケースを作成している。
    • テストの実行、実装の修正をテストケースが全て通るまで繰り返す。
  • プログラミングに限らず、多くの知的な活動の基本は複雑なものを分割して解いていくこと。TDDはそれを実行する手段で、本書に掲載されている例もこれでもかという程細かいステップに分割されている。
    • 問題はどれくらい細かく分割すべきかという点。テストの粒度、グリーンフェーズでどのような実装をするか。これは自分のスキルと取り組む問題に依存するため、客観的な指標でルール化するのは難しそう。
    • ステップの幅を決める手がかりは自分の不安や退屈さになると思う。十分に簡単な実装なら最初から一般化すれば良いし、思ったより時間がかかる場合は途中でも方針を変えてステップを刻む。
  • 方針: 何はともあれ最初にテストを作ることのデメリットは少ないので、そこは取り入れる。ステップの細かさは自分が心地よく作業ができるように随時調整をしていく。

その他実践すること

  • テストケースには数式を直接書く。
    • 何故か今までテストケースには計算した結果を記述し、コメントに計算式を書いていた。最初から数式をテストケースに入れておけば手計算をする必要もないし可読性も上がる。
  • テストファーストにするにはテストを書くハードルを下げる。テストコードも最初は最低限に。
    • テストを作る時は最初から一般性を意識して複数のテストケースを作ることが多い。それが面倒でテストを作るのを後回しにするくらいなら、最初は最も簡単なケースだけにする。
    • テストコード自体もリファクタリングされることを前提にする。コミットとコミットの間で消えるコードがあるのと同じで、一時的なテストだってあり得る。
  • 頭の中の悩みをテストに表現する。
    • 本書では2つの異なるクラスから生成されるインスタンスの不一致性を確認していた。普段は期待値との一致パターンしかしていなかったが、もっと柔軟にテストを考えてみよう。

2. 感想

  • テクニカルな内容も多く書かれていましたが、私としては自分の感情を頼りにステップを細かくすることがTDDの本質だと解釈しました。無理なく取り入れられるところから始めていこうと思います。
  • 訳者の和田さんによる近年のテスト駆動開発の解説がとても興味深かったです。特に以下の一節にはプログラミングを学んでいく上でとても勇気づけられます。

優れたプログラミングテクニックパラダイムは「使いすぎてみて」少し戻ってくるくらいが良い塩梅です。(中略)すべて手を出してみて、夢中になり、正気に戻り、良いと思ったエッセンスを自分の中に残してください。

*1:フロー状態の要素として「直接的で即座のフィードバック」があることが関係しているんだろう。