Is TDD Dead ? のその後

今更 TDD なのか?それとも今から TDD なのか…という疑問が出たのは既に2年前なのですが、状況はあまり変わっていないような気がします。

TDD is dead. Long live testing. (DHH)
http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html
テスト駆動開発(TDD)はもう終わっているのか? Part 1 | 開発手法・プロジェクト管理 | POSTD
http://postd.cc/is-tdd-dead-part1/
テスト駆動開発(TDD)はもう終わっているのか? Part 2 | 開発手法・プロジェクト管理 | POSTD
http://postd.cc/is-tdd-dead-part-2/
Is TDD dead? – YouTube
https://www.youtube.com/watch?v=z9quxZsLcfo

以前、マーチン・ファウラーが Japan XP User Group のために 2002年頃に来日して話した中に

  • TDD はプログラマに安心を与える。
  • MDA はプログラマを殺さないし、今後も大丈夫だ。

というのがありました。折しも「MDA(Model-Driven Architecture)」が発表されたころで、設計者 Model を作って UML のように繋げ、プログラミングの工数を大幅に減らす。そう、ソフトウェア開発の自動化によって大量にプログラマはいらなくなる(昨今の「ロボットに仕事が奪われる」ブームと同じ状態)がありました。当時から、大手ITのゼネコン体制が問題になっていたし、今でも問題な訳ですが(それは社員も含めて「社蓄」と言われているわけですが)そのあたりも含めての「今後も大丈夫だ」の発言です。ただし、ワタクシ的に言えばマクロ的には後退しているような気がしています(個人的には問題ないんですけどね、それは私の年齢的なものもあるので一般化できません)。

それから XP/TDD と言われて「アジャイル開発」という名前のブームも去りつつあり、そもそもソフトウェアプロセスについてのブームが去ってしまい、VRや人工知能、ロボット等の技術的な側面が全面に出てきています。これはスマートフォンやウェブサイトが一般に広まって零細/個人レベルでの売り出し(技術そのものを売る)ことができるようになったからでしょう。だから、内情がアジャイルであれ、ウォーターフォール式の委託であれ、カウボーイプロセスであれ、できあがった「製品」に対しての評価比がプロセス自体よりも高くなったということです。

そういうところで、Webサイトやスマートフォンのアプリを創るときに「TDD」だけにこだわるのはナンセンスです。

が、一方で業務アプリケーションのように十数年レベルで使われているもの(十数年使われていたもの)やインフラ開発のように障害発生時の損失が非常に大きい場合と、数年で消え去ってしまう Web サイトというか数か月でリリースしないと機会損失が発生してしまう Web サイトやスマートフォンのアプリとは別のアプローチが必要になってきます。それだけ TDD 自体の適用範囲が異なるということでしょう。

ただし、TDD にどのような価値があるかといえば「プログラマに安心を与える」のが最初になります。綿密な設計をし組み合わせを考え障害や例外を考慮したフローチャートを書いた後に、慎重なコーディングをした後に、このコードが期待通り動くかどうかを確認するには「ユーザーと同じような操作を画面から行う必要がある」というのは、心理的な負担が大きいのです。設計による試行錯誤、コードの書き換えによってどんな「変化」がおこってしまうかを、ずっと後の工程となる「テスト工程」ではなくて、その場でロジックとして即座に確認できる、というのが TDD の良いところです。この試行錯誤を手軽に扱える道具が TDD の UnitTest になります。逆に言えば、プログラマの安心のためにプログラマ中心の考え方が TDD にあります。

品質を向上するための手段はいろいろある

逆に言えば、プログラマを中心に据えないスタイルで、品質を向上する手段もあります。

  • プログラムコードを書かない設計書からの自動生成(富士通のアレ)
  • スクラム、CCPM をはじめとする、ソフトウェア開発プロセス/マネージメントからのアプローチ
  • 要求定義/開発というスタイルでの、要求の絞り込み (豆蔵のアレ)
  • ワインバーグの提唱する、要求定義工程からの品質の作りこみ
  • カバレッジやプロファイルツールを使い、テストの網羅率や複雑度からのアプローチ (富士通のアレ)
  • テスト工程での QA、不具合混入原因の調査、標準的な不具合発生率の導入
  • 関数型言語などの数学/証明的アプローチの活用
  • フレームワークを活用して、手動で作成する部分を減らす方法 (EJB, EF, Cake等)
  • UMLによるパターンやオブジェクト粒度などの経験的な手法の導入

TDD も含めて、品質を向上する(いわゆる製品の不具合率を下げる)方法はたくさんあります。どれを使ってもよいし、どのような組み合わせをしてもよいのです。ですが、残念ながら人はそれぞれの立場があり、その立場から得る利得のゆえに偏った「手段」を選ぶことがあります。それは TDD/UnitTest も同じ立場ではあるのですが、どこかに偏ってしまったときには、たいていの場合うまくいかない可能性が高まります。

逆に言えば、うまくいかない可能性を低めるのがこれらの品質マネージメントの目標になります。

品質を悪化させるものを削る

スマートフォンのアプリであれ、業務システムであれ、宇宙開発であれ、ロボット開発のためのソフトウェアであれ、要は「要求通り正しく動けばよい」という基準があります(品質工学の考え方で、管理図からはみ出さなければ良い、匠のように中央値に集約させなくてもよい、という考え方です)。特に素晴らしい品質/性能ではなくても、そこそこの品質を保てば平均以上になるということです(Intel プロセスのアレです)。

悪いものを削っていけば、だんだん良いものだけ残るだろうという発想のもとから、品質を悪化させるものを削っていくスタイルを取ってみます。そうすると、先の品質を向上するものが行き過ぎてしまったときに悪さを減らすことが可能です。

  • コーディングの手間がかかる部分で一定の法則があれば、コードを自動生成してしまう。
  • 要求の変更が少ない場合はウォーターフォールで、試行錯誤が必要であればスパイラルで、要求自体が時間軸で変わる可能性があればアジャイルプロセスを適用する。
  • 実装できない/実現の難しい要求を排除する。
  • 過去に実現できた要求を組み合わせて実現する。
  • TDD とカバレッジを組み合わせてテスト網羅率をほどよく観察する。観察した後は、TDD や設計にフィードバックする。
  • 似たプロジェクトあるいは以前のプロジェクトでの不具合混入率や原因をあらかじめ知っておく。
  • 部分的に強固なライブラリとして関数型言語を利用する。複数のプログラム言語を混在させる。
  • 部品が買えるのであれば、購入する。
  • 似たパターンを探し、パターンに沿って作成/ルール化する。ただし、20% の例外がある。

のように、悪化させる要因を減らしていきます。理論的なアプローチのほうが「美しい」と思われるでしょうが、そういう実現可能なものが「工学的なアプローチ」的に美しいものです。

Is Dead TDD のその後

その後、どうなったかといえば「Is Dead TDD」と検索してもさほど有用なデータは出てきません。使う人は使うし、使わない人は使わないという二極状態のような気がします。

おまけ、構造行列を使う方法

鴨澤さんの https://twitter.com/kamosawa/status/688208924764311557 順列組み合わせ絡みとコンポーネント化のところは、デザイン・ルールの「構造行列」という実例があります。この本はコンピュータのハードウェア設計を例にとって、設計時の情報伝達と手戻りのコストを行列として合わらわしたものです。訳本が 2004年で、原著は 2000年出版ですね。

以前、これをもとにして 30 コンポーネント/機能程度の構造行列を出して開発コスト&手戻りコストを計算したことがあります。あるコンポーネントが他のコンポーネントにどれだけ影響があるかを遷移表として調べて、関連を数え上げるだけです。この関連部分を少なくするように設計/UMLを書けば、各コンポーネントの独立度が高くなるため変更に強い(変更に相互影響が少ない)コンポーネント/モジュールが作れるという訳です。

image

[amazonjs asin=”4492521453″ locale=”JP” title=”デザイン・ルール―モジュール化パワー”]

カテゴリー: 開発, TDD パーマリンク