ほげほげ見聞録

技術メモ、備忘録、使い方はそのうち覚える

「テスト駆動開発」を読んでTDDを実践してみた感想

2017/10に発売された「テスト駆動開発」の新訳版を読んだ。
その影響を受けてテスト駆動開発(TDD)を実践した感想などをだらだらっと書いていく。

そもそも、TDDとは何か

当然ながら、詳しい事はググった方が詳しい。
端的に言えば、「最初にテストを書き、そのテストが通るように開発する」方法だ。

以前TDDを調べた時に上のような説明を見たが、何を言っているのかサッパリ訳が分からなかった。
というのも、自分にとってテストとは「プログラムの完成時には必ず全ての項目に丸が付いているもの」だったからだ。
最終的な結果から見れば、「テストが通るように開発する」事は当たり前だと思っていた(出来ているかどうかはさておき)。

テスト駆動開発」を読んでみた

本書では、他国通貨の計算やテストツールをTDDで実装していく例題形式がメインとなっている。
実装する流れを追うことで、まるで著者に弟子入りしたような気分でTDDへの理解が深まっていく。
例題はJavaPythonだが、基本的な構文しか使っていない。これらの言語に精通していなくても、他の言語に慣れているなら問題はないと思われる。

メインは例題部分だが、特に読んでいて発見が多いのは第Ⅲ部と付録だ。
第Ⅲ部はテストとは何かから始まり、TDDの各種パターンを紹介してある。
TDDに限らず開発をする上で有用なチップスが多くあった。
開発の大半はリファクタリングで占められている。リファクタリングの各手法とその方法、理由が丁寧に書いてあり理解が深まった。

付録Cは訳者によるTDDの歴史解説とTDDを始める読者へのメッセージで構成されている。
TDDの情報はネット上に散見されるが、やはりネット情報はバラバラかつ気が付くと消えている。書籍としてまとめてあると分かりやすいし、積読に埋もれない限り消えないのでとても安心。
後半にある「TDDはスキル」「道を照らす明かり」には救われた。
というのも、本書を読み始めた時には開発環境や自身の能力に対する自信がかなり無くなっていたのだ。
テスト書くのは当たり前と世間では言っているが自分の環境では画面確認だけだし、一人でテストコード書くのは気まずいし…といった悩みが消えて、積極的にテストを取り入れてみようという気持ちになった。
プログラムで悩める人は皆読んだ方が良いよ、この文章。

読んでみて分かったのは、TDDは実装の補助ツールのようなものという事だ。
読んで実践しなければ、非常に有効な手法だとは分かりにくい。

TDDを実践する

TDDの良いところは、始めようと思ったその日から一人で始められる点だと思う。
使用する言語の「~Unit」のマニュアルをじっくり読んで、プロジェクトに組み込むだけだ。

どのように実践したかというと、流れは以下だ。これは「TDDのマントラ」と表現されているくらい基本的で繰り返しすること。
処理1で必要なテストを書く→テストがレッドバーからグリーンバーになるよう修正する→グリーンバーになったら処理2に進む…

テストをせずに処理1、処理2…と続けていくと、前の実装を知らない間に壊してしまうことが多々ある。
各処理で自動テストを書いておけば、都度テストを走らせるだけで今までの処理に影響がないことを把握できる。

TDDを実践して良かったこと

  • とりあえずテストを書き始める習慣が付いた
  • 開発途中で出力を確認したいとき、既にあるテストを使いまわせた(時間短縮)
  • リファクタリングの不安が減った

何事も慣れるまでは逆に時間が掛かってしまうという難点がある。
ちょっとした追加開発や小規模な案件で少しずつ始めるのが良いと思う。
自分の場合、一年くらい続いている大規模な案件で始めたら一番最初に書いたテストコードがお粗末すぎて後から直すという事態になったので…。

もちろん、TDDを行うことで全く不具合が無くなるかというと、そんなことはあり得ない(自分はリファクタリングでミスった…)。
あくまで補助ツールだという事を意識して、他のテストとも合わせて使うと確実性が上がると思っていた方が良い。

テストを書く習慣をチームに広める?

自動テストを書いてもいなかったチームで、いきなりTDDやりますって、まず無理。
特に周囲は忙しそうなので、「TDDやりましょう」なんて言っても、まず耳を傾けてはもらえない。
そんな時には、我々でも自動テストできますよって事を分かってもらう必要がある。

ちょうど自分は以下のような自由度が高いプロジェクトに参加していた。

  • 初期の頃から割と自由にコーディングさせてもらっている
  • ちょっとした不具合があってもすぐに対応できる
  • 作業者はメインの自分ともう一人のみ

やったことは簡単で、以下の行動を続けるだけ。
何らかの修正や開発があったとき、しれっとテスト関係のファイルを混ぜてコミットする。

プッシュされた変更は上司がチェック後マージしているが、テストファイルはスルーされていた。
何回かやっていると「最近コミットしてるテストはどうやって実行するのか」と聞いてきた。継続は力なり。

テスト駆動開発」第26章にもあるが、自動テストを広める為にはテストコードとして共有するのが一番分かりやすく手っ取り早い。
一番良いのは、PMとかが号令をかけて自動テストを義務化してしまう方法だろうけど。

そんなこんなで、既存のプログラムに対して自動テストを書いてみるという事になった。
十分なテストとは言えないし、熱心にはやっていないし、やっぱり最近は自分以外やっていない気もするが…。

余談

他のプロジェクトで同じようにテストファイルを追加したら、顧客から指摘されると面倒なので不要なファイルは削除してくれ…と言われてしまった。
結局、テストファイルは自分のローカルリポジトリに残してリモートから削除した。

PGの個人的な努力で導入するにはプロジェクトに依存する、顧客の都合にも影響される事がよく分かった。

今後の課題

TDD及び自動テストを始めて早二ヶ月。
TDDの思想は身についてきたものの、自動テストを書く上で課題が分かってきた。

  • 一つのテストを短くする
  • テストしやすい設計(実装)を心がける
  • DBのモック作成

等々、上げるとキリがない。
TDDを実践する傍ら努力しようと思う。

付録Cにもあるが、TDDは個人のスキルで一人だけでも始められる。
開発をしていると、自分の実装に対する十分なフィードバックが得られなかったり、実装への不安が大きくなったりする時が多々ある。
TDDはそんな時に頼れる開発手法だ。