TDDは死んだ。テスティングよ栄えよ。 by DHH
http://d.hatena.ne.jp/yach/20140424#p1
【翻訳】TDD is Fun
http://diskogs.hatenablog.com/entry/2014/04/25/085112
を読んで思ったことをつらつらと書いてみます。
TDDはできれば、やったほうが良いのは確か?です。
しかし、実際の開発現場で全面的に採用するのは
ミドルウェア等の画面の存在しないソフトの開発以外ではほとんどの場合、無益です。
なぜなら、TDDを採用すると開発時間が膨らむ、すなわち、開発コストが膨らむからです。そして、ソフト開発では細かな仕様は変化していきます、するとTDDではそれに合わせ、テストを修正していかなくてはなりません。
また、TDDで書かれたテストが全てのケースを抜けなく網羅できていることは稀です、抜けは必ず発生します、だからといって、テストコードを
レビューしだすと、開発時間(コスト)が膨らみます。
TDDのもと、テストをしていたからといって、画面のあるソフトでは画面上でのテストは全パターン、行う必要があります。TDDで書いたテストでパスしたからといって画面でのテストを省けるわけではありません。
テストコードにはテストを書いたorレビューをしたエンジニアが想定していないことは反映されません、
画面のある開発でのTDDには掛かるコストを上回るほどのメリットがほとんどないのです。強いて、メリットを上げれば、エンジニアが自分は開発でテストをきちんと行っているという(錯覚かもしれない)実感をもてるというくらいでしょう
か?
TDDに向く、TDDの費用対効果が高い開発は画面のないソフトの開発、あるいは画面上のテストでは全パターンの網羅が難しい箇所の開発等です。
TDDを画面のあるソフトで全面的に採用しているプロジェクトは開発予算が潤沢にある富豪プロジェクトかクライアントからできるだけ多くのお金をいただくために工数を積み上げることが前提の業務用システム開発かにほぼ限られています。
WEBサービスプロジェクト等でTDDを全面的に採用するのはコスト面からみると冒険です。クライアントがあり、クライアントがTDDに掛かる費用を全額負担してくれるなら話は別ですが。。。
TDDやテスト・ファーストは趣味の開発や学生による納期や工数を気にする必要のないソフト開発にはよいかもしれません。
しかし、予算や開発時間の限られる画面のある開発で全面的に採用するのはほとんどの場合リスキーです。
世の中には学生気分のまま、TDDやテストファーストを当たり前に考えていたり、啓蒙していたりする御仁がいらっしゃいますが、TDDは当たり前という幻想は持たないor早めに捨てることをオススメします。
貴方がクライアントor経営者としてTDDによる2重テストのコストを全額負担しますorできますか?
TDDがSIer等の開発現場で産まれ揉まれ実践されてきたテストを含めた開発メソッドと較べて低コスト?で高品質を保証してくれるという幻想は
どこから来たのだろうか?TDDが会社・組織内で実績のある手法を棄ててまで乗り換える価値のある開発手法とは思えない。開発エンジニアの能力頼みで開発メソッドを碌に整備してこなかったプロジェクト・組織・会社では即効性?及び効果のある開発手法なのだろうか???
駄文をお読みいただき、ありがとうございました。
注) 上記の文章での TDD="ユニット"テスト駆動開発 です、学問の世界はしりませんが、国内外を問わず開発現場での一般的な理解です。TDD思想登場時にTDD実践支援用ユニットテストフレームワークが多数登場し、これがTDDであるとその開発者が喧伝?したためにそうなっています。
WikipediaでもTDD="ユニット"テスト駆動開発となっています。(明示されてはいませんが、そのようにしか読み取れません。)
https://ja.wikipedia.org/wiki/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA
TDD(テスト駆動開発)は先ずテスト(ケース)をコードで書き、その後実装しながらそのテスト(ケース)をクリアしていくという開発手法ですので、仕様はfixされておらず流動的であることが前提の(ウオーター・フォール型以外の)開発に
おいてユニットテストならまだしもシステムテストや統合テストでそれを行うのはリスキーを通り越して無謀?だと思います、システムテストや統合テストのテストコード(仕様書?)による駆動は品質確保の観点からは無意味です、ユニットテストなみに全ケースを網羅するなら別ですが、テスト駆動開発でなくてもシステムテストや統合テストは最後に必ず行い想定されうる全てのテストケースをクリアしなくてはいけません、ユニットテストの範囲までシステムテストや統合テストで網羅するのか、という問題はありますが。
解釈を拡大してテストコードを書いていなくてもテストを行っていればテスト駆動開発と呼ぶのなら、どんな開発でも大なり小なりテストを行いながら進行しますので、全ての開発がテスト駆動開発になってしまいます、でもそれをTDDとはいいません。
注) TDDを全面的に採用しても開発時間(コスト)が膨らまない、あるいは微増で済むためには採用するプロジェクトの構成人員ほぼ全ての開発能力が充分に高いことが求められます、実際の開発プロジェクトで開発人員全てに能力の高い人間を揃えられるケースは稀です、それが常にできる企業・組織はほんの一部です、開発現場全ての中の数%にすぎません。
この数%をこの文章では無視しています。
この数%もしくは開発コストの増加(初期コスト・教育コストetc)を覚悟してTDDを導入している企業・組織・プロジェクトでTDDを実践するのは問題ないのですが、そうではない企業・組織・プロジェクトで個人の判断で勝手にTDDを導入して「TDDは当たり前」と力説?されても企業・組織・プロジェクトとしては困るわけですよ、TDDはTPOをわきまえて行いましょう(企業・組織・プロジェクトの流儀には従いましょう)。
注) Capybaraであったり、その他の上位テストのテスティングフレームワークをこの文章では否定していません。開発現場でこれらのツールはTDDと(常に)セットで利用されているわけではなく、ほとんどの場合、TDDとは無関係にテストの自動化のために利用されています、そして、テストの自動化とTDDはは全くの別物です。
テストの自動化は品質確保のために行うテスト時間の低減のために採用されています。想定される全パターンの手動テストを繰り返す場合に発生するコストと想定される全パターンのテストコード(再利用前提)を書くコストを比較して、テストコードを書いて再利用するほうがコストが掛からない場合にです。
注) TDDは不要とは書いていません、TDDには掛かるコストほどのメリットが(ほとんどの場合)ないと書いているのです。
ユニット・テスト・コードのカバレッジの達成率とTDDを結びつけて語られても困るんですよね。TDDで前提となるテスト・コードを網羅性の高い抜けのないレベルで教育なしに自分でゼロから書ける開発エンジニアをほとんどの開発現場ではまず揃えられません。
カバレッジ云々する以前の問題、その前提となるユニット・テスト・コードが先ず問題で、書かれたテスト・コードがカバレッジ云々できるレベルで書けていることをレビューする、場合によってはテスト・コードをレビュアーが修正する必要があるし、そのレベルでテストコードを書けるよう
にする教育(コスト)も必要になります。更に、派遣や外注の方を開発人員としてプロジェクトに多く抱えているプロジェクトでは外注や派遣の方をそのレベルでテスト・コードを書けるように育てても育てる側の組織に属する人間ではないので、プロジェクトが変わる度に教育(コスト)etcが発生します。実社会の開発現場でTDDを実践するには上述したモノを含め、様々な?コストが掛かるのです。
上にも書いたようにTDDをコストの増加なしに実践できるだけのレベルに達しているエンジニアを多数抱え、TDDを実践している会社・組織・プロジェクトはこの文章の対象にはしていません。
そのような組織でTDDを推進している場合には、そのままTDDを推進していってください。
大学など学問の世界?でTDDを持ち上げたり、崇拝?したりするのは勝手ですが、自分を含め自分たちの周りがTDDをコストの増加なしに実践できるだけのレベルに達しているエンジニアばかりだからといって、TDDがリアルで当たり前という幻想をいだくのはやめてもらいたいところです。
TDDが有用であるというのなら、学術の組織内での研究ではなく、実社会の中・大規模開発プロジェクトでTDDでない場合と較べてどれくらいのコストの増減があり、コスト面も含め、どのように有用であるかを示してもらいたいところです。学術の組織内という箱庭の中での研究結果(往々にして小さなプロジェクトでの実践結果)で有用と言われても有用であるとはリアルでは判断されません。
学問の世界で有用とされた開発手法で実社会からは無用とみなされた開発手法は数多?あります。
実社会のプロジェクトであっても東大・京大の出身者等生え抜きのエンジニアで構成された開発プロジェクトでの実践結果は現実の開発現場のほとんどでは全く参考になりませんので。そのような例を出されても、TDDが有用であるとは考えませんので悪しからず。
(言わずもがなですが、実社会の営利目的でする仕事には会社・組織・プロジェクトからみると全てコストが掛かっています。そして、それはソフトウェアの開発現場でも同じです。掛かるコストに見合うメリットのない開発手法は会社・組織・プロジェクトでは受け入れられません、
ある開発手法に掛かるコストに見合うメリットがあるかは会社・組織・プロジェクト毎に判断されます。特定の会社・組織・プロジェクトがその開発手法にメリットがあると判断したからといって、それが他の会社・組織・プロジェクトにとってもメリットがあるわけではありません。)
注) 少し真面目?に書いてみる。
DHHは『TDD≒Test Firstをやってきたけど、実装する前にテスト・コードを書きそのテストに通る実装を書くのは、テスト・コードにmockが必要だったり、実装への制約になったり、実装している最中により良い設計?を思いついた際に、その方向で実装していくと後からテスト・コードの変更が必要になったりして面倒、だから、これからはTDDをやめて「Implemantation first」「Test second」「No(t) Test-less」な方向でいくよ、ユニット・テストをしないわけじゃない、しっかりするよ、テスト・コードも書くよ、実装ありきだけどね。画面をテストする際にはCapybaraとかも使ってるよ』と書いてるようにみえる、要約すると(超訳かも。。。)。
自分も「Implemantation first」「Test second」「No(t) Test-less」な方向でいいんじゃないかと思ってる。
個人的にはTDDのテスト・ファーストに抵抗感が、、、なので、TDDを強制する環境では仕事したくない。実装(モノづくり)が目的なのであって、テストが目的のわけじゃないので。(※個人の感じ方の問題です。)
自分は先ず実装してからテストしてるし、実装時間以上にテストに時間を掛けてることもままある、場合によってはテスト・コードも書いてる。
テストは品質のために必要だけど、できれば、テスト時間(テストに書けるコスト)は最小化したい、テスト・ステージ(ユニット・テスト、システム・テストetc)毎に同じテスト・ケースを何度もテストするのはできれば避けたい。
それに画面があるソフトウェアでは実装してから画面で確認(テスト)すれば済むレベルのことまで、わざわざ全てテスト・コード化しておくのは不毛(と感じる)。
多くのクライアントや利用者にとって品質はあって当たり前のモノ、最低限の品質をクリアしていないモノは使ってくれないけど、品質に金を払ってくれるかというとそうでもない、最低限の品質さえクリアしていれば、品質はそんなに気にしない。
大きな不具合があれば問題となるが、小さな問題ならクレームがつく程度、きちんと対応すればノープロブレム。品質に必要以上にコスト(≒お金)を掛けても意味はあまりない。
例えば、日本の電化製品、品質は良いけど、海外では売れないよね、高品質のために掛けたコストが全て製品価格に上乗せされてるから。
日本人技術者は高品質に価値をおきすぎ。
テストを全て?コード化するTDDにはコストが掛かるし、採用するプロジェクト・組織・会社にはそのコストを吸収できるだけの体力?が必要。
そもそも短納期のプロジェクトを回している組織・会社ではTDDの導入に伴う初期コストを掛けられない(吸収できない)場合が多い。(そのような会社でTDDに即対応できるエンジニアを多数抱えていることは稀。)
TDDをやるだけの地力のあるプロジェクト・組織・会社で開発エンジニアに先ずテストを書くことに抵抗がなければ採用し、上手くいけば、プロジェクト・組織・会社で推進していけばいい。けれど、自分たちのトコロで上手くいったからといって周りも全て上手くいくという幻想をいだくのはやめてもらいたい。
それにTDDはSIer等の開発現場で産まれ揉まれ実践されてきたテストを含む開発メソッド(プロセス?)との親和性が低い、というか、ない。プロジェクト・組織・会社内で既に実績のある開発メソッドを棄てて乗り換えるほど大きなメリットは
TDDにはない。
注) 同じテストを何度も繰り返して行う必要のあるプロジェクトでのテスト自動化の有用性は否定していません、しかし、レグレッションテストのためのテスト自動化とTDDは全くの別物です。
レグレッションテストの回数が多い場合にはテスト・コード化するコストを手動テストのコストが上回るので、テスト・コード化するほうが良いのは言わずもがなです。
そういう自分も https://github.com/asip/meteor etcにてレグレッションテストのためのテスト・コードを用意していたりします。demoの中にあるのがそれです、テスト・コードとして利用しています、流した結果は目視で確認していますが。
TDDのメリットとされていることの全てはTDDだからできるという類のものではなく、TDDでなくてもできるのです。TDDを絶対神聖化?する意味が全くわかりません。
コメントにて書かれている方もいますが、現在、WEBアプリではJavascriptの高速化及びデバイスの高速化によりクライアントサイド(ブラウザ)でより多くの処理を行うモノが増えてきています。UIまわりでは要素へのエフェクトの適用、要素の表示・非表示等を行い、視覚的に魅せることが必要になってきたりもしています。
全ての主要ブラウザの挙動は全く同じという幻想をいだいている方もいらっしゃるかもしれませんが、ブラウザ毎に微妙に挙動が異なるケースは多々あります、特にUIまわりでは。UIまわりで色々とやっているWEBアプリでは主要ブラウザ毎にテストをして目視で確認する必要があります。テスト・コードの自動化ではUIまわりの挙動の
チェックはできません。WEBアプリに限らず、画面のあるアプリでは画面の目視による確認は必須となっています。
SIer等では既にTDDの評価は行なわれ、その結果、TDDを構成する個別要素のうち有用なものは会社・組織内で作成・錬成してきた開発メソッドに既に組み込んでいます。会社・組織内で実績のある開発メソッドをTDDベースに置き換えるよりもTDDから良い所どりしたほうが会社・組織にとって有益であると判断されているのです。
注) 上の記事で「TDDが死んでいる」と書いていると誤解している人がいるようなので、追記しておきます。TDDが死んだ、とは思っていません。TDDはテストの強制ができる点で意味があると考えています、とかく(自分も含め)エンジニアはテストをなおざりにしがちなので。。。
でもTDDをやるにはそれなりにコストが掛かる、実際の開発プロジェクトでそのコストを受け入れられる条件の整っているところは全体的にみれば案外少ない、TDDを銀の弾丸・唯一絶対の特効薬みたいにいうのはやめようよ、という話です。
TDD自体を否定しているわけではありません。TDDのコストを受け入れられる条件の整っているところでエンジニアにテスト・ファーストに抵抗感がないのであれば、TDDを採用し推進していけばいい、また、TDDのコストを受け入れられる条件の整っていないところはTDDを部分的に採用して(=TDDの構成要素のうちプロジェクト・組織・会社にとって有益なモノを取り入れて)やっていけばいいのではないか?と思っています。
(狭義の)TDDはテスト・ファーストを前提とした一枚岩の開発手法であると理解しています。
今の時代、取捨選択のできない一枚岩の開発手法ではあらゆるニーズに対応することは不可能なのではないでしょうか?
はじめはTDDには向かないタイプの開発もあるよね、と書いていたのが、途中からTDD自体に対する是々非々?みたいになってしまっています。。。
他) コメントに小規模ソフトウェアハウスの方?による、自分のところではTDDの導入に挫折・失敗したこと、周りにもTDD導入の失敗事例があることからTDDは銀の弾丸・唯一絶対の特効薬ではないような気がするとの書き込みがあったとき、それに対してその方をけなす?ような書き込みがTDD信奉者?の方から書き込まれていました。
けなしていないにしても、相手の意図?を汲み取る努力を放棄し、自分たちの主張を一方的に押し付けているようにみえました。
書き込まれた方は二度とTDD界隈には近づくまいと思ったはずです。
どのようにすれば上手くいく、例えば、TDDをはじめから全て実践するのではなく、はじめはテスト・ファーストはせずに、他の構成要素を(部分的に)導入して、そこから徐々にテスト・ファーストにもっていくとうまくいくよ等の、(TDDの導入に再トライしてみようと思わせるような)建設的なアドバイスができたはずです。
TDD信奉者の方?は自分たちのところが特に苦労することもなく(※程度の問題です、素養?のある集団であれば、ない集団に較べて、という話です。)上手くいったから周り全てが苦労することなく上手くいくと錯覚しているように思います。
TDD信奉者の方?は自分(たち)を普通のエンジニアと思い、自分(たち)を基準にしているのかもしれませんが、あなた方のほとんどは「3聴けば10わかる3聴けばそこから自分で大した努力もなし?(※程度の問題です、素養?のある人であれば、ない人に較べて、という話です。)に10にたどり着ける」人のはずです。
世の中、3聴けば10わかる3聴けばそこから自分で(努力して)10にたどり着く人ばかりではないのです、10理解させるためには10教えなくてはならない(自分での努力を放棄している、生活費を稼ぐ手段としてエンジニアをやっているだけ・いわれた仕事をするだけで技術そのものに全く関心はない・勉強のために自分の時間を使う気もない)人(くれくれ君?)、(既に習得した技術にしがみつき)新しい技術の習得に消極的で前向きに取り組まない人もいっぱいいるのです。
素養?のある人(集団)とない人(集団)とでは開発手法等を導入する際に掛かるコストに(大袈裟かもしれませんが)天と地ほどの開きがあるのです。
http://www.slideshare.net/t_wada/osh2014-sprit-of-tdd/44
にあるMS・IBMでの導入事例をTDD信奉者?の方が持ち出されていましたが、導入結果と導入しない場合の数値による比較・被験者アンケートの内容、導入から得られた知見についてしか触れられていません(被験者?集団の構成や適用したプロジェクトの詳細については何も触れられていません)。
MS・IBM等の大手IT企業は3聴けば10わかる、3聴けばそこから自分で大した努力もなし?(※程度の問題です、素養?のある人であれば、ない人
に較べて、という話です。)に10にたどり着ける人の集団です。
この導入事例をみてTDDの導入に踏み切る人はいないのではないでしょうか?
TDDの導入を検討しているところは、どうやればうまくいくのか、導入した会社ではどういう手順で導入していったのか、自分(たち)のところで適用可能かの判断材料を知りたいのであって、導入した場合と導入しない場合の数値比較等を知りたいわけではありません。
注) 趣味や学術研究での開発でもない限り、「テストにはコスト(お金)が掛かる」のです、「テスト・コードを書く」のにも、当たり前ですが。(学術研究であっても、それを仕事してやっているのなら、コストが発生しています。)
テスト・コードは書けば終わりではなく、テスト・コードに対する動作確認も必要になります。それもまた、コストです。目視でテストすれば、一瞬で確認の終わる内容に対して、テスト・コードを網羅的に書いて、テスト・コードを目視でテストして、テスト・コードが通った後に本体を網羅的に目視でテストするのはコスト面で無駄な気がします。
テスト・コードは万能ではなく、その作成・メンテナンスにコストが掛かる上に、テスト・コードを通ったらテスト終了ではなく、その後に目視でのテストはほとんどの場合、必須です。
使い捨てのソフトや頻繁に変更の発生しないコードなら、目視でのテストで事足りるので、デグレを気にしてテスト・コードを書く必要はありませんし、開発中に仕様が変わり、書いたテスト・コード(の一部)を捨てることになったり、テスト・コードの大幅な書き換えが必要になることはザラにあります。仕様変更の場合、本体を修正し目視でのテストで動作を確認してから、テスト・コードを修正・テストすることになったりします。
全てのケースでテスト・コードを網羅的に書くのはほとんどの場合、コスト面からみるとナンセンスだと考えています。開発者の自己満足のための網羅的なテスト・コードに対して誰がそのコストを負担してくれるのでしょうか?開発の予算に限りがある以上、開発に掛けられる期間にも限りがあり、その中でテスト・コードを書くのに掛けられる時間にも限りがあります。
趣味のプロジェクトでもない限り、プロジェクトの予算が限られている以上、その中で品質を担保するために掛けられるコストは限られています。
(趣味のプロジェクトであっても、趣味に掛けられる時間が限られている以上、その中で品質の担保に費やせる時間は限られています。)
仕事としてのテスト・コード作成・メンテナンスを作成者が無報酬で徹夜してでもやってくれるのなら話は別ですが(趣味なら、網羅的にテストコードを書きたい方は自分の納得いくまで、時間を掛けて書けばよいと思います)。
他) TDDで開発者の安心とやる気が担保される、という主張はわけがわかりません。
TDDが他の開発手法よりもトータルのコストが掛からないというのであれば、根拠となる実例を示して下さい、大学の研究室の実験での結果や趣味での結果は根拠にはなりえません。
(今まで、テストがおざなりであったプロジェクトに本来のTDDを導入した場合、大概はプロジェクトが破綻すると思います、)
TDDの根幹?は、「テスト・コードで品質を担保する」ことにあると考えてます。
TDDの原典?には「テスト・ファースト」と明記されています。実装よりも先にテストを書き、そのテストを通る実装を書く、のが本来のTDDです。なので、TDDにおいては本来、テスト・コードを網羅的に書くことが前提であり、網羅的でない虫食いのテスト・コードでは、TDDの効力が半減どころか、TDDを実践する意味自体がないに等しいと思います。
本来のTDDでは、テスト・コードの(品質・)網羅性がそのまま、実装の品質に直結します、
テスト・コードの(品質・)網羅性が低ければ、実装の品質も自ずと低くなります。
実装する前に必要なテスト・コードを網羅的に書けるエンジニアが揃っているプロジェクトが世界にどのくらいあるのでしょう?
実装中にテスト・コードを実装にあわせて修正しているTDDプロジェクトは山程?あるのではないかとも思います。
開発中に開発しているソフトやサービスの仕様がころころ変わるプロジェクトも山程あります。そのようなプロジェクトではTDDを実践するメリットよりもデメリットのほうが大きいと思います、他の方がすでに書かれていますが。
テスト・コードを書くことで、安心する、や、やる気がでる、と感じている職業エンジニアは稀だと思います。品質を担保するために必要だから、クライアントの安心に繋がるから(クライアントから要求されているから)、テスト・コードを書いている職業エンジニアが大半ではないでしょうか?
テスト・コードを書くことは有用だと考えています。ただ、コストが掛かるので、テスト・コードをどこまで書くのか(品質の担保をどこまでテスト・コードに頼るのか)を予め設定しておく必要があると思います。
テストはテスト・コード(だけ)に頼るのではなく、手動でのテストを含め、(コスト面を考慮
した上で、)トータルで考えるべきモノだと思っています。