👌

「テスト駆動開発」を読んで 一週目 Kent Beckの思想を感じる

2023/08/20に公開

はじめに

皆さんはテスト駆動で開発はしていますか?
私はしていません。
ただ、憧れ?みたいなのはあって、この度書籍「テスト駆動開発」を購入しました。
試しに読んでみると、面白く共有したい気持ちがわいてきたので今回記事を作成しました。
ただ、今記事は実装の解説を行いません。
あくまで、読んでみてどう感じたかしか書いていませんのでご留意ください。
実装を含めた解説は2週目に行います。
また、自分が読んで面白いと思った部分を抽出しているので、各項目に繋がりはありません。
そのため、気になった部分だけ読んでいただけますと幸いです。

テスト駆動の勘所は?

「テスト駆動開発」を読んで感じたのは、テストを書くことが目的ではないと感じました。
テストは設計と実装の乖離をなくすための手段という側面が強い気がします。
テスト駆動開発は以下のルールによって、行います。

  • 自動化されたテストが失敗した時のみ、新しいコードを書く
  • 重複を削除する
    そして、上記ルールを守って開発するには以下の流れになります。
  1. テストに失敗するコードを書く
  2. テストを通すためにコードを書く
  3. リファクタリングをして、重複を削除する
    と、良く聞いたテスト駆動開発の手順を記載しましたが、この方法には最も重要な
    \textcolor{red}{実装のTODOを書く}
    という手順が抜けています。
    テスト駆動開発はテスト技法ではなく、設計手法です。
    これは「テスト駆動開発」のP. 278でも言及しております。

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

テスト駆動開発は、テストコードを書くことでバグを発生しないようにする技法ではありません。
機能に対しての実装方針と実際の実装がずれていないことを担保するために、テスト駆動開発は行います。
よって、テスト駆動開発をする場合、実装のTODOが必須項目となります。
TODOなくテストから書くのは、テスト駆動開発ではなく、テストファーストというテスト駆動開発の中の1手順に過ぎません。
テストを書くことを最重要ではないと思ったのは、書籍の中で以下の流れを繰り返し、繰り返し行っているためです。

  1. TODOを確認する。
  2. テストを書いている際に気づいた、追加で実装すべきことをTODOに残す。
  3. 最初に取り組んでいたTODOを実装まで完了させる
    また、テストの書き方やリファクタリングの方法について言及はありますが、章として設けているのはデザインパターンについてしかありません。
    このことからも、テストやアプリケーションコードをどう書くかについては、別途開発者自身で他の書籍を読むなりすることで対応してほしく、「テスト駆動開発」で伝えたいテスト駆動開発の要点はTODOを作成し、綺麗かつTODO通り動くコードを書くという流れを維持することだと感じています。
    以上から、テスト駆動開発の勘所は設計と実装の乖離を無くすことだと結論づけました。

テスト駆動開発は開発者を最強にするのか

テスト駆動開発を行うことで、開発者は完璧な存在になれるかを見ていきます。
なお、この章では「完璧な存在」を以下の要素を全て満たしている人と定義します。

  • バグが一切発生させないシステムを作ることができる
  • 今後バグが発生することが困難なコードを書くことができる
  • 実行速度が最適化されているシステムを作ることができる
  • セキュリティリスクが一切ないシステムを作ることができる
    当たり前ですが、テスト駆動開発を行うことで上記のような完璧な存在にはなれません。
    まず、バグを発生させないシステムを作れるかについてですが、確かにテスト駆動開発によってバグは少なくなります。
    それは、設計と実装をテストコードによってずれを無くすことを行っているため、実装においてミスが発生する可能性が低くなるからです。
    しかし、バグを一切発生させないシステムを作ることができると言うのはあまりに極論が過ぎます。
    テスト駆動開発で行っているのは、開発者が自分で実装したものが考えた通りに動くかの確認です。
    そのため、開発者が考慮できていないもの、本来は搭載しなければならない機能だが設計の時点で漏れていたものに対してテスト駆動開発は対応できません。
    ただ、バグが将来発生しにくいコードを書くのはテスト駆動開発でかなり対応できます。
    これは「テスト駆動開発」目的が「動作する綺麗なコード」だからです。
    動作する綺麗なコードは自分を含めた開発者が、どこまで開発が完了していて、各コードの意図を把握しやすくなります。
    進捗が見え、内部の構造も理解しやすければ何が必要で、どういったバグが起きやすいかを認識しやすくなります。
    これらのことから、テスト駆動開発はバグが発生しにくいコードを書くことにかなり寄与します。
    最後に実行速度とセキュリティについてですが、これは全くの範疇外です。
    書籍の中でも、セキュリティと実行速度を含めてテスト駆動できるようにするのは今後の課題と言っているように、現状これら二つの対応をテスト駆動開発ではカバーできません。
    以上から、テスト駆動開発は万能な道具ではなくても、保守性を持った実装に対してかなり貢献すると言えそうです。
    テスト駆動開発で最強の開発者にはなれなくても、周りの仲間から信頼されやすいエンジニアにはなれそうです

テスト駆動は全人類が行うべきなのか?

煽りのような見出しを書きましたが、私みたいな若輩者が判断できるものではありません。
とはいえ、テスト駆動開発をする目的はしっかりと認識する必要があります。
テスト駆動開発が扱っている領域と、テスト駆動はどのような問題を解消をするために編み出されたのかを理解してから、使うべきだと感じました。
と、テスト駆動開発はかくあるべきだと記載しましたが、著者のKent Beck、翻訳者の和田卓人さん両名とも、ちゃんとしたテスト駆動開発ができないなら、しない方がよいとは言っておりません。
一度テスト駆動開発を正確に体験すべきだと言及していますが、その中で役立つエッセンスを抽出して自分なりのプログラミングスタイルを確立していけばよいと述べています。
以上のことから、チームとして導入するならちゃんと目的などの認識を合わせる必要がありますが、個人でやる分には好きにやったらいいのではないかと考えています。

「テスト駆動開発」を読まなくてもいい人

ここではテスト駆動開発を読まなくても良いと思う人を挙げていきます。
なお、ご注意いただきたいのですが、私は「テスト駆動開発」を全人類が読んだ方がいいと思っています。
ただ、「テスト駆動開発」を読んだ方が良い理由については、すでに溢れるほどの良文が出回っています。
なんなら、「テスト駆動開発」で和田さんが書かれた訳者解説がその一つです。
以上から、「テスト駆動開発」は読んだ方がいいとは思っているが、周りの状況からあえて読まなくていい人を抽出していることをご留意ください。

読まなくていい人①: 優秀な開発者

優秀な開発者は「テスト駆動開発」を読まなくても問題ないと思います。
ここでいう「優秀」とは、頭の中でイメージした実装と実際の実装にずれが生じない人のことをいいます。
頭の中とずれなく開発ができる人はすでにテスト駆動開発が目的していることを概ね達成しているので、「テスト駆動開発」を読む優先順位は低いです。

読まなくていい人②: プログラミング初心者

プログラミング初心者は、「テスト駆動開発」のコードを実際に手を動かす状態まで持っていくことが難しいと思うので無理して読まなくてもよいと思います。
ここでいう「初心者」とは自力でJavaとJUnitの実行環境を用意できないひとのことを言います。
「テスト駆動開発」のコード自体はそれほど難しいものではありませんが、書籍の中に環境構築手順など動かすための手順は展開されていません。
そのため、実行環境は自分で作成する必要がありますが、初心者は環境構築をできないので、先にJavaやJUnitを動かせるように勉強するのが先だと思います。
よって、プログラミング初心者も今すぐ「テスト駆動開発」を読む必要はないです。

おわりに

今回「テスト駆動開発」を読んで感じたことについて書きました。
テスト駆動開発は実装と設計のずれをなくすための設計技法と言えます。
テストケースは実装のTODOと実装の架け橋となります。
テストケースを書くことは、TODOをコードに落としこむ第一歩です。
テストケースを書いた後に、どういった検証を行うのか考えます。
検証したい値を設定したら、それらを呼び出す手順を書きます。
手順が実行できるように実装を行います。
テストが通ったらリファクタリングを行い、重複を削除します。
テストケースによって、開発者は自分のメモ帳のみ書いていたTODOを他者に見せることができます。
テストからコミュニケーションが生まれるのです。
繰り返し、繰り返しテスト駆動開発はTODOをコードで表現する方法だと言っていますが、そもそもどういった実装をTODO化すべきなのかについての詳細はありませんでした。
これについては、別の領域な気もするので記載されていないと推測しています。
最後にですが、「テスト駆動開発」を読む場合は実際にコードを書いてみるのが大切だと思っています。
実は1年程前に、「テスト駆動開発」を読んだのですが、その際は手を動かさずに読むだけでした。
コード自体はそれほど難しくないので一応読めて、テスト駆動開発の手順については覚えたのですが、テスト駆動開発は何を目的として行っているかまで理解できませんでした。
一方で、今回「テスト駆動開発」を読んで手を動かしたら、テスト駆動開発の目的について理解できるようになったと感じます。
テスト駆動開発の知識については、手を動かさずに読んだときと吸収したものに違いはなかったですが、なぜテスト駆動開発を行うのか、テスト駆動開発はどのような目的を達成するのかといった、全体的な理解の厚みは格段に変わりました。
この厚みが変わった瞬間は誰かに話したくなると思いますので、是非とも「テスト駆動開発」読んでみてください。

二週目へ続く

Discussion