こちらの講演時にいただいた質問への回答です。

「テスト自動化とテスト駆動開発」講演資料 - やっとむでぽん

質問7. TDD導入に関する質問です。 実際にテスト駆動の場合は、最初のリリース時は以前に比べると工数、費用はかかり、運用保守まで考えて効果がでてくるはず。最初のリリース時の費用はどうしても上がりそうです。 それを顧客に説明するときの考え方、作戦、政治、などが気になります。他社導入時の工夫など事例はありますか?

f:id:yach:20210407143822p:plain:w350

難しい質問ですね…ご質問ありがとうございます。前提とするプロダクトの状況によって、考え方が変わってくると思いました。1.初期開発なら、テスト駆動開発工数が増えることはありません。2.既存システムの再開発や、保守運用では、先行投資が必要になります。いずれにしても、3.一人前に作業できないなら、それは仕事でやって大丈夫?という話になります。もう少し詳しく説明します。

新規開発ならシンプル

新たなソフトウェアを新規開発する(1.)という幸運な状況では、最初からテスト駆動開発を導入するのがベストです。単にテストが自動化できるだけでなく、目の前の仕事をより品質よく実装していけるので、進みは速くなりますし、デバッグや再テストで取られる工数も減ります。スライドではこちらのデータを紹介しました(スライド81)。

f:id:yach:20210407143646p:plain

そもそも、テスト駆動開発を使いこなせる人であれば、それを「まったく使わない」という選択肢はありません。「ぜんぶテスト駆動で書く」「部分的にテスト駆動で書く」といった選択肢がありますし、実装する部分(フロントかバックエンドか、ビジネスロジックかボイラープレートか、フレームワークを利用するかどうか、など)でも最適なアプローチが違いますし、さらにレッド・グリーン・リファクタリングのサイクルを守る度合いも調節できます。ルール化するなら、「プロダクトコードにはテストコードを書く。タスク完了時(コミット、プルリクエスト、コードレビュー依頼など)には、必ず両方揃っていてテストはグリーンであること」というくらいがいいかもしれません。熟練者であれば状況によって選択肢を選べるので、必ずしも厳密にテストを先に書かなくても、サイクルを大きく1日1回くらい回すのでも、ちゃんとした結果を出せます(これは初級者は真似しないほうがよいです)。

和田卓人氏(タワーズエスト)の講演「質とスピード」では、コードに対しテストを書いてきれいな状態を維持することが、開発スピードの向上につながるという話が繰り返しされています。またMartin Fowlerの言葉として、「品質の低いコードは、数週間でスピードを大幅に遅くしてしまう」(“Developers find poor quality code significantly slows them down within a few weeks.”)と紹介しています。こちらのスライドは、開発スピードに関する重要な知見を含んでおり、読んでみるのをお勧めします。

f:id:yach:20210407143722p:plain

speakerdeck.com

再開発や保守運用は工夫が必要

さて、新規開発ではなく、既存システムや保守運用の場合(2.)は話が変わってきます。いまからテストを自動化するというかなり重大な先行投資が必要になるためです。この負担をまるごと一括で顧客に求めるのは、かなり難しいと思います。

ひとつのアプローチは、細く長くテスト自動化を内部で進めていき、徐々に内部の工数が減っていく効果をねらうというものです。細く長く工数を確保しないといけない話ではあるので、厳しい面もあるとは思います。いっぽう、現場のメンバーが何名かいて、TDDやテスト自動化をやってみたいというモチベーションがあって、仕事の中で時間を捻出して自主的に進めるというのは、よく見る姿です(工数を確保してあげられないのはブラック風味ではあります)。組織の共通予算のようなところから、戦略的にどこかのチームに投資するという選択肢も、あるかもしれません。予算(工数)確保であったり、スキルあるメンバーがやって来てパートタイムで手伝ってくれるなどです。

そもそも投資である

3番目の論点は、テスト駆動開発や自動化が初めてです、という人にお客様の仕事をさせるのでしょうか?という話です(3.)。これは開発サイドから見ると投資です。開発機材を最新化したり、未知の言語を勉強したり、新しいクラウドアーキテクチャを試してみるというのと、同じ意味で投資です。そうした投資の話をお客様とできる関係性なのであれば、ぜひ説明していただければと思います(コンサル的役割で説明のお手伝いもできるかもしれません)。

投資をお客様に求められる状況にないのであれば、初めてのテスト自動化をプロジェクトの予算でやるわけにはいかないでしょう。勉強、練習の工数は別途確保して、ちゃんと仕事で使えるようになってから仕事で使うという流れになります。スクラムを導入して、ちゃんと改善をまわせているチームであれば、改善をするという時間を確保しているはずなので、その中で勉強・練習をすることになります。

勉強と練習をするのはそんなに長い時間ではなくて大丈夫でしょう。勉強だけの時間が1週間(40時間)あったら素晴らしいですが、そこまでやらなくても、いったんできるようにはなると思います。そこからは仕事の中でやっていくことになりますが、書くテストの種類や、フレームワークの取り扱い、データベースの扱いなど、自分たちのプロダクトの環境で必要になるやり方を調べたり、編み出したりしていく必要もあります。最初の勉強から、プロダクトでテストを書くやり方があるていど安定するまでは、経験者や外部のメンターなどがいるほうが安心です。

勉強と練習をするのは、実際のところ自分たちはどのくらいのスピードで進めるのか、それを見極めるためにも必要です。納期とスコープが決まっていて、それに間に合わせないといけないのなら、実際の仕事の環境でスピードを計測するのはリスク対策としても必須です。やってみて、明らかに間に合わないなら、いまは諦めるという選択肢が採れます。テスト駆動開発でやると決定してから、それでは間に合わないとわかるのでは、手遅れになってしまうかもしれません。現実問題としては、練習してできるようになったうえで、その前提で見積もるはずです。

回答が長くなって恐縮ですが、懸念となる点を図で整理するとこうなるのかなと思いました。

f:id:yach:20210407143822p:plain

(字が読めなかったらごめんなさい。「現在の生産性とそれを基準とした見積り」「TDD勉強中~試行サクゴ中の生産性」「TDD上達後の生産性」です)

  • Bの生産性は本当にAより高くなるのか、どのくらいなるのか?
  • 勉強や試行錯誤で生産性が下がるCの期間はどのくらいかかるのか?
  • Cの期間中の仕事はどう見積もるのか?
  • Dの投資をどう捻出するのか?

こうした疑問には、申し訳ないですが私には回答できません。現状によるというところもあるし、結局は人次第の面もあります。Cを圧縮するためDを深くする、あるいは逆にCを引き延ばしてDを薄くするというような作戦もありそうに思えます。

私自身の、何年か前にアジャイルコーチとして支援したチームで、まず普通に作ったシステム(テストなし)に対し、エンハンス(保守)の中でテスト自動化とテスト駆動開発導入に取り組みました。なので既存システムのシナリオ、ただし初期メンバー(けっこう優秀)がそのまま追加開発をしている体制です。そこではかなり感覚的ですがBはAの1.2~1.3倍、Cは半年くらい、Dは主にメンバーのモチベーションで捻出した(ただし内製なので政治的な話にはならない。開発チームがビジネス側を説得した)、という感じです。

TDDではなくテスト自動化で考えると、プロジェクト全体で見て、手動でテストする方法と、テストを自動化する方法、どちらが工数面で有利かは、状況によると思います。すみませんが私には、そのへんのノウハウがありません。「自動化するだけで安くなる」はまやかしですが、手動と自動をうまく使い分ければトータルのコストを下げられる可能性はあるのではないか、少なくとも選択肢として俎上に載せられるのではないかとは思います。