組織にテストを書く文化を根付かせる戦略と戦術

社内講演会に和田さんに来ていただきました。僕も聴講できたのでそのメモです。基本から、最近の知見まで、まんべんなく丁寧に説明いただきました。

戦略編

アジャイルサムライはアジャイルソフトウェア開発を広く浅く説明した本。入門書としてお勧め。
アジャイルなプログラミングに必須なプラクティス

「テスト」が重複している?
リファクタリングユニットテストに依存している。なので、ユニットテストリファクタリング、の順。
ユニットテストリファクタリングは、いつ行なうかについては語っていない。それらの有用なプラクティスなので、早い段階から不断に行ないたい。それがテスト駆動開発

「動作するきれいなコード」テスト駆動開発の価値であり目標。

「設計をしない」は誤解。ただし、文書化したり承認を得たりするかというとこれもまた違う。

TDDの黄金の回転の中で、消極的になってなおざりにされるのがリファクタリング
リファクタリングは普段の生活における掃除のようなもの。普段からまめにやっていれば簡単だが、ためると大変。
大変なことをするには上司の許可とか必要になり、いよいよやり難くなる。
リファクタリングは普段からついでにやるしかない。

労力をかけて自動テストを書き溜めたのは、テストのご利益を求めるから。なのに、実際にはいつもテストを直している手間ばかりかかって利益が感じられない。つまり、テストコードもリファクタリングする必要がある。そして、それは(プロダクションコードの場合と同様に、あるいはそれ以上に)溜めずに不断に少しずつやるしかない。テストのテストは、現実的には、書いた直後にしかできない。

テストの理想はMICE。

ユニットテストのサイクルの外側に、アクセプタンステストのサイクルがある。さらに言えば、その外側にリリースとデモがあり、…

テスト駆動開発は、「ギャップをコントロールする技法」(テスト駆動開発入門、ケントベック)

「Testing vs Checking」にならえば、TDDのテストは、一周目だけはTestingであり、二周目以降はCheckingである、といえるだろう。

誰が何のために(大きさやタイミングは無視して)

  • 開発者テスト(開発促進)
  • 顧客テスト(進捗確認)
  • QAテスト(品質保証)

テスト駆動開発工数が2割増え、バグが8割減る(MS, IBMの実践事例報告から)

どの職場にも有効な、テスト駆動を定着させる方法はない。

「テストを書く時間がない」は、テストがない→不安→テストかけない→の悪循環。ケントベックの回答は、自動テストを書く→ストレスが減る→テスト書く余裕ができる→の好循環。

陥りがちな失敗:理想を追いすぎる。現状をかなぐり捨てて理想に挑む。
処方:着地可能なToBeを作って、自分たちに合ったペースで進める。

小さく始める。アンダーザテーブルから。

技術的負債の四象

テストは品質を上げない。テストは品質を可視化する。見えたものを改善(設計とプログラミング)するからよくなる。

戦術編

どこからやるか?一番困っているところから。バグ修正のところから(バグは偏在するという意味でも効率的)、静的解析のスコアの悪いところ、など。(リーン開発の現場)リスクが高くて、手動コストが高くて、自動化コストが低いもの、で並べて、上から取り組む。

全員で始めるのは大変。できる(向いてる/キーになって欲しい)人からすこしずつ。例えば若手のホープから。

こだわらない。全部、テスト駆動、テストファーストユニットテスト、実行速度、網羅性、モック、等々。徐々に。

レガシーコード改善ガイド
レガシーコードのジレンマ、テストがないからテストが書けない、に対する処方箋

  • 「仕様化テスト」のすすめ
  • 「絞込み点」を探す。たとえばWebアプリであれば、requestとresponse

見える化
メトリクスを取る(最近の静的解析ツールはいろいろな数値を取ってくれる)
静的解析ツールは警告が死ぬほど出るので、一番ゆるい設定から徐々に進める
メトリクスは変化を見る
静的検証ツールは対象コードを動かさないで評価できるという特質をうまく使うべき

コードレビュー
インフラに投資しよう
githubはgitをhostしたから栄えたわけではなく、レビューやリクエストをうまく扱えるから栄えた。この点を学び取り入れることを考える。
コードレビューをするから質が上がるのではなく、コードレビューされると思うから上がる

実装をなぞったテストを書くと、実装を直すときに必ずテストを直すことになる。これはコスト的に合わない。そのコードのインタフェースをテストする。あまり細かなインタフェースをテストしても同様なので、ある程度の大きさのインタフェースをテストする。

現場の取り組み

  • サンプルとデモ
  • 真似してもらう
  • テストのある生活を体験してもらうのが最初に大事
  • 次にテストのメンテ

テストの質を測るには(実験的なものも含め)

  • バレージの重複を測る(実験的)
  • プロダクトコードをわざと壊して検出できるか試す(実験的)
  • レビューする(現実的)

量を増やすときに品質も上げる
最初はとにかくテストがあることのよさを体験してもらうことが最優先
次に増やしてメンテナンスすることが大事になるので、最初の段階を過ぎたら意識する
よいテストコード:だいたいプロダクトコード同じ価値観

コーディング時間は増えるが不具合対応は減る。前工程に倒れるのでプロジェクトの完了見込みが見えやすくなる。受託開発にはこれ大きい。

感想

以下は一般論ではなくて、僕の仕事から考えた感想です。
現状リリースまでの期間だけで考えるとTDDするメリットはあまりないと思う。しかし、そのコードが継続的に保守されることを考えるなら、動作するだけでなくきれいなコードである必要がある。それを維持するための治具としてのユニットテストセット、維持するための習慣としてのTDD、の必要性はあるだろう。
オブジェクト志向でないコードに対するユニットテスティング、git-flow的ワークフロー、テストと込みで書かれテストをパスしているコードのレビューはこれまでのレビューとどう違うか、詳細設計は無くしていいか、代わりになにか必要か、などの考察の余地があるだろう。