希薄化したTDD、プロダクトの成長のために必要なものは?〜『健全なビジネスの継続的成長のためには健全なコードが必要だ』対談 (6)

『健全なビジネスの継続的成長のためには健全なコードが必要だ』対談も遂に完結です。最終回は「付録Cの書かれた狙い」と「未来に向けたテスト」が語られます。

--

『テスト駆動開発』

前回の対談では「付録Cを書いた動機」を和田さんに聞いてみました。前回の「TDDの教条主義化」に続き、対談の最終回は「TDDの意味の希薄化」そして「付録Cを書いた狙い」についてです。

テスト書くのが当たり前、だけど・・・

和田:次に意味の希薄化ですね。『Test-Driven Development by Example』の出版から15年経ち、テストコードを書く人はすごく増えました。15年前は啓蒙期で、テストコードを書きましょう、テストコードの書き方はこういう感じですというのを頑張って啓蒙する必要があった。

でも、例えば今の若手プログラマーは普通にテストコードを書く。なぜなら既存システムにはテストコードが書かれているから、開発の継続、不具合の修正とか機能追加を行う際にテストコードを書くのが普通だし、テストコードが無いとレビューは通らないしみたいな話になって、テストコードがあるという生活は普通のものになっている。そうすると、なぜテストコード書くのかとか、本来こういうテストコードを書きたかったんだけどとか、こういうテストを書くべきなんだけどみたいな議論はだいぶ土俵から外れてしまって、テストは書かなければならないので書く、みたいな感じになってしまった

家永:「不安を取り除くために自分が自信を持って」のはずなのに。

和田:「不安が退屈に変わるまでテストを書く」とか「壊れそうな、危なかしいものに対してテストを書く」みたいな、ちょっとフワッとした言葉で初期アジャイリストたちが言った言葉が、今は「テストを書かなければならないからテストを書かされる」になった。

つまり(TDDは)権利じゃなくて義務になっちゃっているんですね。今の若者にとってテストというのは、やらなきゃいけない、まさに「テスト」みたいに義務化されてしまったもので、自分たちの不安を取り除くためにテストコードを書いているんじゃなくて、やれと言われているからしょうがなくやっている。内発的じゃないんですよ。

家永:本来は、自分自身が、コントローラブルなものを増やしていくという活動の中にテストの自動化があって、そこにリファクタリングというのを自信をもってやりながら、要望に応えていくというところを作っていきたいはず。それが、嬉しい気分の維持のために(自分自身の意思で)前のめりにテストとリファクタリングをやっていくというよりも(誰かに言われて)やれとなっている。

和田:やれと言われるからやる。だから、得てして変化を助けるテストコードになってないんですよ。実装の追認でしかないテストコードになっている。「私はこういうふうに実装しました」というテストコードを書いてしまいがちなんですね。

家永:よくカバレッジだけ追っかけて。

和田:そうですね。

テストコードの目的・意味が失われてきた?

家永:(プログラマーが)内部の設計やリファクタリングに関して、あまり思い入れの無いまま。

和田:リファクタリングが射程に入ってないテストコードになっちゃっている。ソフトウェアの内部の質は、テストコードを書いても基本的に変わらない。リファクタリングしないと内部の質は上がらないのに、リファクタリングを行うという発想がそもそも無くなっちゃっている。テストコードは増えるし、テストカバレッジは増えるんだけど、ソフトウェアの設計自体は全然良くなっていないという結果になってしまう。「私はこういうふうにコードを書きましたというような、こういう仕事をしました」という証明のためだけのテストコードみたいな。

家永:あー、基準が80%あるから、そこを達成しました。(そこまで)

和田:やはり現状の追認になっちゃっているんですよね。私はこういうコードを書いたからテストコードもこうなっておりますみたいな話になっちゃっているんだけど、そうじゃなくて、そこから先に行くための足場になってほしいのがテストコードなんですよね。まだ見ぬ良い設計を追い求めるための足場になってほしいのに、そうじゃなくて、いまの設計はこうなっております、きっちりとちゃんと仕事してますという証言をするためのテストコードみたいになっちゃっていて、生き生きしてないんですよ。

家永:わはは。

モックも意味が失われてしまった

モックオブジェクト(http://xunitpatterns.com/Mock%20Object.html より)

和田:例えばモックオブジェクトとかも、本当は生き生きとしたソフトウェアを作るためのカナリア(※1)になるはずだった。モックオブジェクトは、インタラクションベースの設計を行うための道具であり、モックオブジェクトが書きにくいなというのは、設計が良くないから設計を良くしていくという原動力になるはずだった。しかし、モックオブジェクトを作るためのモックライブラリーの機能競争が起きた結果、モックライブラリーはどんどんどん機能が多機能化されていき、できることが増え、強力になればなるほど、設計改善効果がどんどん薄れていってしまった

(※1) カナリアが炭鉱で毒ガス検知のために使われていたという話に基づく、危険を察知するテストの意味(詳細はこちら)

家永:プライベートは何だと。

和田:プライベートメソッドのモックもできますとか、スタティックメソッドのモックもできますみたいな。(Javaの)インタフェースがなくても、既存のクラスに対して部分的に実装を書き換える(パーシャルモック)みたいなこともできますという方向に機能拡張されてしまって、モックは皮肉にも既存の実装のままで無理やりテストをするための道具にどんどんなり下がっていくんですね。本当はモックはもっと非力でいい。

家永:設計を助ける。

和田:そう。非力なモックを使うことでイライラを感じて設計の方を改善していかなきゃいけないのに、強力なモックライブラリによって、

家永:(へんてこな設計やコードのまま)動いちゃった。

和田:そう。とにかく強力な機能を使って、既存の機能を無理やりテストするため、カバレッジを上げるための道具に成り下がってしまった。それって現状の追認じゃないですか。汚いコードだけどモックをこう使ったらテストできるから、ぼくは仕事できてますよみたいな、そういう話になってしまって、全然生き生きしてないという話ですよね。

家永:そういうのはいくつか見てきたと。

和田:たくさん見てきた。テストを何のために書きたかったのかとか、モックオブジェクトは何のために生まれたのかみたいな背景や思想、過程が全部無くなってしまって、道具だけが残った

思考過程が失われて名前だけ残っているから、「RSpecを使って「テスト」を書く」みたいなことが平気で言われてしまう。BDDの語彙と、TDDの語彙というのは、ほぼ横並びで等価な単なる方言になってしまったので、テストコードを書く際にお好みのスタイルをお選びくださいみたいな感じまで矮小化されてしまった。たとえば、test、assert、suiteなどの名前を使っていたらTDDスタイルで、describe、context、it、expectなどを使っていたら、BDDスタイルというような。それって単なるビューのスキンを変えますみたいな話であって、本当にそんな理解で良かったのかみたいな話になるんです。

…というのが、意味が希薄化して失われ、ツールだけが残っている現代のテストの現状です。なぜある人は「テスト」と言い、ある人は「スペック」という名前を好むのか(※2)。過程とか意味付けとかそういったものが全部失われちゃって、テストを書かなきゃいけないものであって、この言語のこのテスティングライブラリではこう書きますみたいな情報ばかりが見つかる。道具しか残っていないので、背景や思想、文脈を復活させる必要がある。それが付録Cです。

(※2) BDDは「テスト」という言葉が持つ「検証」という意味に偏ってしまうことがTDDの本質とかけ離れてしまっていると考えたDan NorthやDave Astelsらが「振舞(Behaviour)」という言葉が持つ「振舞(仕様)の定義」という意味を強調することで、TDDが持つ本来の意味を強化しようとした取り組みだった。BDDの当初の目的についての解説はこちら

家永:なるほどね。

和田:いまその付録Cがいろんな人に読まれ、「付録C」という名前が独り歩きし始めているんですけれども、でもそういった失われたものをつなぎ直す役割をする文章を、このタイミングで書けたのはありがたかったと思います。

家永:なるほどね。

懸田:それを家永さん聞きたかったのね。

家永:そう、これは聞いておかないと。わははは。すいませんね、ここはべらべらしゃべらない。

和田:いやいやいや。

家永:どうしても聞きたかった。

和田:すごい面白かった。いいんじゃないですか。

天野:そこに関心があるというのは家永さんらしさ。

付録Cは文脈をつなぎ直すために書かれた

和田:始まりは森田さんの提案なんですけど、言われてみれば、歴史をまとめるだけじゃなくて、背景を伝える意味でも、やらないとならない感じ、書きたかったから書いたという側面はある。例えば付録Cの現在編は、なぜ、いまこんな事になっちゃっているのかというのを、コンテクストをつなぎ直して整理したかった。

家永:自分も今ブログで記事書いているんですけど、TDDの歴史の部分は確かに「被った」と思いましたけれども、その先の問題提起とか、そこに関しては自分そうは考えてなかったです。なので、何だろうというのが知りたくて一つ聞いてみました。無理やりコードは変えずにテスト通してしまうとか、それは確かに起きている。

懸田:それは、テストという側面しか見てないからそうなっちゃうんだと思います。

家永:キーワードとして、テストというキーワードが前面に。(リファクタリングや設計が後ろに)

和田:前面に出ちゃうとそうなる。例えば、検収要件としてカバレッジ何パーセントという条件が出てくるとかは、既存の実装に対してその動作を保証してほしいという重力が強いんですよね。

既存の実装の現状肯定じゃなくて、未来のコードベースに対して発展と成長の可能性をキープしていく意味合いでのテストコードの価値というのは、ほとんど話題に上らない。既存の実装に対して、みんなこだわり過ぎという話はある。

いまこう動いています、こうなっておりますと現状追認に、どうしても重力が発生してしまって、その先にコードベースを変えていく際に、こういうテストコードがあるからこんな感じで前向きになれますという意義が、失われがちであるという。

「これなら戦える」を支えるもの

「これなら戦える」

家永:話を聞いて僕が思ってたのは、二番目で一緒にやったやつの引き継いだ時(※3)の感覚ですね。結構、設計判断、前はこうだったけどやめたというのは結構あって。さっきの要望にこたえるためのモデル変更の話もそうだけど、当時は永続化の所を疎結合しようする設計判断でやっていたけど、これは分かれて出したり、差し替えることはないなと分かった瞬間に、これは密(結合)でやったほうがいいと判断した。

(※3):対談第一回を参照

和田:間接層を一つ。分かる。

家永:密、密、そっちの方が間違いが少なく早く作れるよという、分かれることはない、そういう判断をあとから結構やっていた。

和田:いい話だと思います。そういうのが現場の生き生きとした判断だと思うし、最初からすごく抽象度の高い間接層をたくさん伴った設計をするより、自分が現場の視点を持っていて、その判断の中でベストのソフトウェアのアーキテクチャを求めた結果、ひとつ間接層をすっ飛ばすなんてすごい良い話だと思った。

懸田:それができたのも、ちゃんとテストが整備されていたから自信をもってできたということなんですかね。

家永:あともう一つ、テストの整備の仕方も教わったというところはあります。

懸田:そこもセットでね、テストがあっただけじゃなくて。

和田:そうですね。テストコードを書きっぱなしにしないで、ぬか床みたいにメンテしていく

家永:当時は小さいユニットテストも力を入れつつ、ファンクショナルテストもやっていたんだけど、ファンクショナルテストの足場は少し道半ばの所があった。(もう一つがデプロイテスト)。どれなら僕は自信を持って戦えるだろうかというところで、その時に選んだのは、真ん中のファンクションテストの強化だった。

和田:そうですね。

家永:だから「これなら戦える」というところで、真ん中に(テストを)入れたりとか。

和田:「これなら戦える」という感覚は大事ですね。

家永:これなら戦える。最初、モデル変更にビビって、その当時のPOと話をしていた時は、文字通り足を取って手をついて、こんな状態(orz)で、「ああっ、これどうしよう?」という失意の中思っていました。その足場を整える中で、二日ぐらいかけたのかな?一日ぐらいかけたのか、ちょっと忘れたんだけど。

和田:一日、二日かけてテストの見直ししたり。

家永:その中間の道半ばの戦いにくかったところを、もうちょっと戦いやすい足場を作るというのをやって、それでモデル変更してバリエーション作れることができた。

和田:良い話ですね。

家永:怖かったモデル変更を、自信をもって変えていくというのができた。

和田:変更に対してこれなら戦えるというのは、それこそが前向きな状態です。

最後にひとこと

対談を終えてポーズ!

家永:そろそろねということで、一言ずつということで、どっちから行きますかね。

和田:今日、久しぶりに家永さんと対談できて、だいぶ久しぶりですよね、きっとね。

家永:対談なんかしたことないです。相談会とかしたことある。

天野:ランチ会とかしましたね。

和田:過去のプログラミングとかコンテクストとか案件とか、いろいろなものを共有している人と対談する機会は実はなかったので、すごい楽しかったです。「生き生きとしている」とか、そういったキーワードとソフトウェア設計と実際の行動というのを結び付けて話すのも、普段はあまりないので、それも良かった。

パターン言語と、ソフトウェア設計と、普段のプログラミングを一つのつながった世界にあるということをもっと意識したり、読み手とか聞き手の人に意識してもらう場はあまりないので、貴重な場でした。パターンにも付録Cが必要なんですよ。歴史が切れてしまっている所があって、パターンってGoFのデザインパターンでしょ?みたいなところがあったりするから、やはり背景や意義を補わなければならない。そういうのを何か思い起こすきっかけになりました。ありがとうございます。

家永:江渡さんの本じゃダメなの?あれ、でも絶版?(※3)

(※3) 『パターン、Wiki、XP ~時を超えた創造の原則』(技術評論社)は、C.アレグザンダーの『パタン・ランゲージ』が、Wikiやエクストリームプログラミングにどう影響を与えているのかの繋がりを綿密な調査を元に明らかにした良書。電子書籍版が技術評論社から入手できる

懸田:(パターン、Wiki、XPは)絶版です。和田さんありがとうございます。じゃあ家永さん。

家永:「コードの中に住んでいる」というのは、そうそう、そうだよというのを、和田さんに力強く言ってもらったシーンがすごく印象に残っています。自分とコードの距離感という感覚を、普段感じているはずなんですよね。触るのに不安を感じているとか、そこに対して自信を持って前に進めているのかって「心地よいのか」とか、前任者への「ありがとう」みたいなのを思いながら何か書くのか、そういう感覚がもっと普通に広まっていって、自信を持って前に進んでいくプログラミングをする世界がもっともっと広まっていくといいな。そういう一つの思いで、今日のテーマとして「健全なコードが必要だ」というのをセッティングしました。

懸田:全然一言で終わらない。なるほど。お二人にとって楽しそうで良かったです。

和田:では懸田さんからひと言。

懸田:僕はすごいちゃちゃ入れたかったけど我慢しました(笑)。とても面白かったです。いろいろ(ホワイトボードに)書いたりもしましたけど、いろんな文脈がありそれを知ってるので、自分なんかは「そうだよね」と理解できるんだけど、そのあたりの文脈がロストしていると、こういう話を聞いても腹に落ちないのでしょうね。それは別にこの業界だけでなく、全ての世界において文脈が抜け落ちて形骸化する現象が起きるんですけども。

以前から、こういう文脈も含めてちゃんと新しい世代に伝えていくというところを、和田さんは真摯に取り組んでいるというのを感じています。和田さんは僕より少し下の世代ですが、和田さんがおじさん呼ばわりされてショック受けながらもやっているというのを見ていて、すごいと思います。

天野:和田さんがおじさんなんだ。(※4)

(※4) 天野が和田さんと初めて出会ったのは、まだ20世紀の頃のパターンの勉強会で、当時和田さんはまだ学生でした。

懸田:ただ何かを伝えていくというのは、エバンジェリストみたいな人や、ボブ・マーチン(※5)のように、いくつになっても「俺はお前が生まれ前からコードを書いているんだ」みたいな人が伝え続けるやり方もあるのですが、それだけではないとも思いますね。例えば(伝え続けるための)組織を作るとか。

たとえ書籍を書いても、その本が若い世代に読まれるかどうかは別の話なんですよね。和田さんはある意味ライフワーク的な感じでやられていますが、こういった大事なことを伝えていくやり方は、いろんな人と考えた方がいいかもしれないなと感じています。

(※5) ロバート. C. マーチン、愛称「アンクルボブ」とも呼ばれるソフトウェア開発者。Agile Manifesto(アジャイルソフトウェア開発宣言)の宣言者の一人であり、『アジャイルソフトウェア開発の奥義』『Clean Code』『Clean Coder』などの著者でもある。

懸田:あとテストの話なんかで思ったのは…あ、全然俺も一言じゃないね(笑)「今やっていることがなぜ必要なのかを伝える」「そもそもこういったものを要らないようにするのはどうするか」「いろんな達成すべきゴールというのに意識を向けていく」ということに対して何かできるといいなと思いました。テストを頑張って書かなくても「生き生き」できるような仕組みとかね。いろんな妄想が生まれたすごい良い会でした!

和田:ありがとうございます!

家永:ありがとうございました!

--

--