Perfectionism、「完璧主義」ですね。「まだ自分の設計は対象システムの世界を完璧に捉えられてはいない。ような、無用なこだわりです。プロジェクトマネジメントの世界では一種のアンチパターンとして知られていました。アンチパターンであるからには名前がついていて、みなさんもご存知かもしれません。日本語では「分析中毒」と訳されます。私自身は「完璧主義の呪い」とよく表現しています。分析中毒の影響は強く、この象限に長い時間滞留して、終わりのない問いをぐるぐると追い求めがちです。「ずっと設計し続けるわけにもいかない」といった意見も出始めます。コードを書き始めることにします。ここまで考え抜いてきた設計を実際にコードに書いて動かし始めるわけですね。動作する」象限に遷移を始めます。すると、縦の線、ピンクの線を越えた途端に、様々な情報が開発者にフィードバックとして返ってきます。「考えに考え抜いたつもりで、もう完璧だろうと思ってコードを書き始めようとしたのだけど、実際にその設計をコードに書こうとしたら、なぜか手が動かない。考えに考え抜いたつもりだったけど、細部に関してあまり考えられていなかった。具体的にどこがどうなるべきかまでは考えられていなかった。設計の焦点が合っていなかったことに気づかされます。私個人も、最初に考えた設計でクラスを書き始めたらコンパイルすら通らず、調べたらプログラミング言語が提供しているグローバルオブジェクトと名前が重複していたからだったみたいな経験もあります。一種の予約語だったのです。気づいてしまう」ことも多々あります。考えに考え抜いたのだけど、今回はそもそもそこまで考え抜く必要はなかった。今回の要件においてはそこまでやる必要はなかった。「もっとシンプルに考えればよかったのに、どうもやりすぎてしまったな」と、設計が複雑すぎることに作り始めてから気づいてしまうかもしれません。「こういうこともあろうかと」という、エンジニアの価値観を体現した言葉があります。「こういうこともあろうかと」は、その予想が当たらなければただのコストになってしまいます。設計ができて、それを無理なくコードに落とすこともできた。動かしてみたらパフォーマンスが悪すぎて使いものにならない」ことに気づいてしまうかもしれません。2019年においても、ソフトウェア開発においてたくさんのフィードバックが得られるタイミングは、実際にコードを書き、それを動かすときです。実際にコードを書き始めることによって、はじめてコードの書きやすさや読みやすさがわかり、現実的に動作することもわかり、それだけでなく、自分は何が欲しかったのかが本当にわかりはじめます。実際に書いて動かしてみればわかる。書いて動かしてみないとわからない。2019年の現在においても、ソフトウェア開発においては、たくさんの現場がそういった現実に向かい合っています。これは2019年においてもソフトウェア開発は工学になりきれていないことのひとつの証左だと考えています。いうことかというと、簡単に言えば予測可能性と再現性が低いんですね。予測可能性と再現性が高ければ、以前と同じ方法で今回も成功するはずです。5年前と同じやり方ではなぜかうまくいかない。5年前から現在までの間で様々なものが変わってしまっているからですね。ソフトウェア開発の世界では、様々なものが同時に、同時多発的に変化していってしまいます。それは今後もしばらくは続くだろうと予測できます。この業界は、変わるものが多すぎるのです。OSも、ハードウェアも、ブラウザも、言語も、フレームワークも、開発環境も、開発手法のトレンドも、5年前に動いていたやりかたを、今日寸分の狂い無く再現することはできません。率直な表現をするなら「書いて動かしてみるまでわからないことがまだまだ多すぎる」というのが現実です。スライドの図でいえば縦の線、ピンクの線を越えるタイミングが後ろになればなるほどプロジェクトはリスクを抱えることになります。プロジェクトはデスマーチへと一直線に進んでしまいます。これが、ソフトウェア開発の現実です。そんなことを聞くと「オレンジのルートはちょっとまずいんじゃないか」と思えてきて、青いルートの方がまだ比較的、相対的には「まし」に見えてきます。動作する」を目指すルートでした。動作するけどきたないコードを書き、それを動くままできれいにしていく方がまだ「まし」に思えてきます。実際に『テスト駆動開発』を読むと、青矢印のルートを薦めているように読み取れます。最初に「動作する」に取り組み、その後で「きれいな」に取り組むとあります。青いルートのほうが有望そうだと思い、青いルートを進み始めます。するとどのようなことが起こるでしょうか。動作する」を目指すコースでした。「まず動くコードを書いて、あとからそれをきれいにしていけばいいじゃないか」という考え方です。こちらのルートも実は罠があり、一筋縄ではいきません。オレンジのルートには羞恥心や虚栄心、完璧主義の呪いや分析中毒などの沼地がありました。きたない」コードの象限に沼地があります。この沼地の障害物や、開発者が抱く感情はどのようなものでしょうか。Laziness、「堕落」とか「怠惰」と表現できます。プログラマの三大美徳のひとつの怠惰ではなくて、本当の、文字どおりの怠惰です。「まあ動くからいいじゃないですか」という話ですね。「わざわざきれいにするのはちょっと面倒じゃないですか。きれいにするのはまたの機会にするとして」などと言って、この象限にとどまってしまいます。Impatience、「焦り」や「焦燥感」です。プレッシャーと言い換えてもいいでしょう。スケジュールのプレッシャーです。「コードをきれいにすることなんぞに時間を費やすな。機能を作れ」などと、他者から外圧としてやってくるプレッシャーもあります。ひとつ、開発者をこの象限に縛り付けている感情があります。この3つ目の感情が最も強く、この感情がソフトウェア開発の業界を長い間ずっと縛り続けていました。「恐怖」、「恐れ」です。「ようやく動くところまでやってきたソフトウェアを、これからきれいにしていく過程で壊して動かなくなってしまうのが怖い。「壊れて動かなくなってしまったら元も子もない」というような恐怖、恐れです。いう感情が、ずっと長い間、強く、この業界を縛り続けてきました。「きれいだけど動かないソフトウェア」と「きたないけど動くソフトウェア」では、言うまでも無く後者に価値があります。コードは、動作することによって価値を提供します。「きれいだけど動かないコード」にしてしまうことを極度に恐れてしまいます。そのような強い「恐怖」、ソフトウェア開発の業界を縛る強い感情を体現した言葉があります。みなさんも聞いたことがあるかもしれませんし、なんなら自分から誰かに言ったこともあるかもしれません。それは、どんな言葉でしょうか。その言葉とは「動くコードに触れるな」です。私は実際に聞いたことがあります。みなさんも聞き覚えがあるのではないでしょうか。いう強い恐れを象徴した言葉であり、ずっと長い間この業界を縛り続けてきました。ソフトウェアは手を触れなければ動き続けるものではない、というのはもうおわかりかと思います。悲しいことに、動くコードに触れなくとも結局動かなくなってしまうのがこの業界です。それでも昔は、動くコードに触れなければ、ある程度安定していた、例えば汎用機の時代などはありました。いう笑えない話が始まってしまいます。昔と今で違うのは、いろいろなものが変わっていく、その速度や頻度です。コードに一切手を触れていなくとも動かなくなってしまいます。言えば、そのような受け身の姿勢ではビジネスに勝てなくなってしまいます。技術的負債はどんどん溜まり、ソフトウェア企業としての開発力、競争力は相対的に落ちていってしまう。結局、動くコードに手を触れなければならなくなるわけです。前向きな理由であれ、後ろ向きな理由であれ、動くコードに手を触れなければならない。かかわらず、動くコードに手を触れ続ける準備をしてこなかったから、毎回爆弾処理のような心理状態でリリースをしなければならなくなるのです。「動いてくれ、頼む」と祈りながら作業することです。自分に根拠はないし、正直いま動いているかどうかすらよくわかっていない。コードを変えてリリースしなければならないから、あとは祈るしかない。やってソフトウェア開発を続け、リリースを続けなければならなくなってしまう。この業界では、まだこのようなやり方でリリースしている企業もありますし、こういうやり方を強いられている人もたくさんいます。やりたいのはこういう開発のやり方ではないですよね。毎回爆弾処理のようにリリースしたくはありません。自信を持って動くコードに手を入れ続け、競争力を高め続けられるようなソフトウェアを、私たちは作りたいのです。呼ばれている状態です。それは、安心して積極的にコードに手を入れることができて、もしそれに失敗してしまっても、すぐに失敗に気付けるし、すぐに元に戻せるので壊滅的なことにはならない状態です。私たちに必要なのは、このような環境を作り、開発文化を作ることではないでしょうか。触れなくていいソフトウェアをつくる、例えば一度作って納品したらメンテナンス不要のソフトウェアが最高のソフトウェアであると考えられていた時代もありましたが、今はそういう時代ではありません。変化し続ける、変化し続けられるソフトウェアの方が資産になる時代です。触らなくていいソフトウェアよりも、積極的にかつ自信を持って触り続けられるソフトウェアの方がずっと価値があるのです。これが昨今のソフトウェアの姿であり、そのためには、リリースのたびに爆弾処理のような思いでリリースをしていてはなりません。全てが変わっていく世の中で、変化に対応できなければソフトウェアも事業も緩やかに死んでいきます。爆弾処理のようなリリースとは、つまり勇気ではなくて蛮勇、度胸であり、度胸で開発しているからあんなことになるのですよね。なく、私たちはエンジニアなのだから、道具と技術をもって恐怖に対抗するのがエンジニアのやり方です。ソフトウェア業界を強く縛り付けてきた恐怖に対して、蛮勇ではなく道具と技術をもって対抗する手段を探し育てる方向でソフトウェア開発の世界は進化が続いてきました。道具と技術を探しに行きましょう。今日のソフトウェア開発の世界において絶対になければならない3つの技術的な柱があります。三本柱と言ったり、三種の神器と言ったりしていますが、それらはバージョン管理テスティング自動化の3つです。これら3つの技術は、あれば競争力がある加点法ではなく、無いと競争力が無い減点法の世界です。そもそもこれらを備えるところからスタートしなければなりません。これらの技術は人間の限界を補い、能力を補完するために生まれ、いまの三本柱の位置まで来ました。ソフトウェアは時間を経るごとに複雑になっていく宿命を負っています。人間は3年前に書いたコードの詳細を覚えているでしょうか。それどころか1ヶ月前さえあやしいものです。人間には人間というハードウェアが持った限界があるのです。ソフトウェアの開発を健全に続けるためには、機械が人間の能力を補完してさらに伸ばしていく方向に進化していく必要がありました。バージョン管理システムは、人間の記憶力の限界を補うために生まれました。先ほど言ったように、人間は3年前のコードを覚えているかあやしいどころか、1ヶ月前さえあやしいです。いった人間の代わりに、バージョン管理システムが、いつ、だれが、どんな変更をしたかを逐一記録してくれます。人間はバージョン管理システムの使い方だけ覚えていれば、変更の詳細までは覚えていられなくとも良くなりました。バージョン管理システムの使い方くらいは覚えておいて欲しいということでもあります。そのとき誰がどんな変更を行ったかも取り出せるようになりました。これが、人間の能力を補う、身体の延伸としてのバージョン管理システムです。スライドの写真は、15年前のシステム開発の現場です。だれが、いつ、どんな変更をしたかは当然覚えていてくれるのですが、ブランチとマージの管理がまだ貧弱でした。マージしたかは覚えてくれませんでした。どこからどこまでマージしたかを紙に書いて記録していました。これをバージョン絵巻物とかブランチ絵巻物と呼んでいました。やってくれますが、当時は手作業が必要でした。バージョン管理の進化の途中で、人間の作業がまだ必要だった時代の話ですね。ある程度成功したプロダクトは開発が続くもので、ブランチ絵巻物は会議室の端から端に届くくらいまで伸びていきました。全て管理してくれていました。これだけ長い期間の開発をバージョン管理ツール無しでやったらどうなっていただろうかと考えると背筋が寒くなります。これが三本柱の1本目、バージョン管理でした。個人的な意見では、バージョン管理は他の柱よりも格付けが上で、正直なところバージョン管理が無いと話になりません。バージョン管理ツール無しでシステム開発に臨むのは、一切セーブしないでロールプレイングゲームのクリアにチャレンジするようなものです。2本目の柱はテスティングです。テスティングは人間の把握力の限界を補います。書き続け、行い続けることによって人間の把握力の限界を補います。「あのとき動いていたもの」が「今もその通り動かせるか、動いているかどうか」はわかりません。動きますくらいしか言えないでしょう。いま目の前で開発しているシステムが果たして想定通り動いているのかどうかわからなくなってきます。いった危うい土台の上で開発している開発者は、全体の把握が難しくなればなるほど、慎重で近視眼的になり、設計判断も保守的になっていきます。いった事態が始まります。断言できないからこのようなことになってしまったのです。いった開発の現場が向かう先は、結局はソフトウェアの緩やかな死です。1年前にこう動くべきと自分が考えて書いたコードは、いまこの瞬間にも当時の想定通り動いているということだけは、断言できるようになります。少なくとも当時考えていた通りには、いまもソフトウェアが動いていることを、ごく短い時間で確認できます。それだけでもだいぶ大きな前進です。問題」のような「あなたはコードが動かないと言うけど、私のところでは動きますよ」といった問答も減らせます。やってテストと共に作られてきたソフトウェアの上で、いま開発している機能は仕様も実装も頭の中に入っているうちにテストコードを書きます。そのとき自分がどういう変更を行ったかはバージョン管理システムが覚えてくれている。ツールが人間の能力を大きく補ってくれているのです。これからもテストと共にコードを書いていくことで、これから書くコードにも自信を持つことができます。自動化は人間の忍耐力の限界を補います。ソフトウェア開発は小さく定型的な繰り返し作業が非常に多いという特徴があります。ひとつひとつは小さいタスクの繰り返しでソフトウェア開発は成り立っています。当の人間は、そういった単純な繰り返し作業がとにかく苦手です。決まったことを寸分違わず繰り返せと言われても、だんだん飽きてくるし疲れてきます。飽きたり疲れたりすると作業の精度が落ちていきます。人間は基本的にこういう性質を持っているのです。基本的な性質としては、創造性は人間よりも劣るけれども、繰り返し作業に強い。機械は与えられたタスクを疲れずに淡々と同じ精度で続けることができます。人間の得意不得意、機械の得意不得意をそれぞれ相互補完しようというのが自動化の考え方です。手順書の代わりに自動化スクリプトを書きます。すると、それまで人間の手数が15ステップの操作手順だったものが、たとえば4つのスクリプトを順番に動かせば良くなるだけになります。1つのボタンを押すだけで作業が完了するようになる、といった具合です。人間が必要な手数を減らし、人間は頭を使い、機械が代わりに仕事をする方にシフトしよう、という考え方ですね。そのように作業のステップを減らしていって、1アクションでできるところまで行ったときに、人間はさらにその先を求めます。1アクションすらしたくない、と思い始めるのです。人間は基本的には怠惰な生きものだからですね。Autonomation(自働化)があります。トヨタ生産方式(TPS)の言葉で、自ら動くではなく、自ら働くと書きます。読みが同じですから、後者は「ニンベンの付いた自動化」と呼ばれたりもします。いうのがトヨタ生産方式の自働化の考え方です。アクションの向きを逆にしたのですね。異常なことがなければ何も伝えてこなくて良い。便りのないのは元気な知らせというわけです。すると、人間と機械の協業は完全に非同期になります。人間は人間のペースで創造的な仕事を続けていれば良くて、何かおかしなことがあったときだけ機械が割り込んでくる状態を作れます。Autonomation(自働化)の世界です。継続的インテグレーションです。ビルドやテストが失敗したときだけ開発者に知らせてくれれば良くなります。コードの変更がなくとも、CIサーバは決められた間隔で常にビルドやテストを繰り返し、失敗したときは開発者に知らせてくれます。いう、なんと言いますか、お洒落系インテリアです。電子回路につなぎ、テストが失敗したときに赤いランプが点灯することで人間がテストの失敗に気ける仕組みを作りました。実はこれはトヨタ生産方式の「アンドン」のアイデアを、インテリアグッズで実現してみたのです。このように、自動化の世界では機械が人間のクリエイティブワークに割り込んでくるときの割り込み方を工夫してきた歴史があります。ここまで三本柱や三種の神器といった例えの話をしてきました。実は私は三本柱ではなく「三脚椅子」のメタファーをつかっていました。三脚椅子にはバージョン管理の脚と、テスティングの脚と、自動化の脚があります。椅子は倒れてしまい、座り続けることはできない。ソフトウェア開発は頓挫する。3つのスキルは1つもおろそかにしてはならない、という例えとして、うまく説明できていたつもりでした。仙台で講演していたとき、ある人によってこのメタファーは論破されます。人間にはもうひとつ安定している状態があるじゃないかというのです。脚がゼロ本でも上に座ることはできるのです。バージョン管理がなくて、テスティングがなくて、自動化もなくても上に座ることはできる。木の座布団みたいな話で屁理屈に見えますが、確かにメタファーとして隙がある。その「事件」があってからは、わたしは三脚椅子で例えることをやめ、三本柱とか、あるいは三種の神器と言うようになりました。武器を携えて、再び戦いの場に戻ってきました。動作する」象限でした。「きたないけど動作するコード」をきれいにしていく過程で壊して動かなくなってしまうのがとにかく怖い。ソフトウェア開発の世界を縛り続けてきた「恐怖」です。その恐怖を度胸や蛮勇でどうにかするのではなく、エンジニアだったら技術や道具で克服したい。いまや手元に三本柱、三種の神器があります。恐怖を克服し、蛮勇ではなく技術と道具によって星を目指す準備ができました。技術と道具によって、どうやってきたないコードをきれいにしていくか。その代表的な技術が「リファクタリング」です。よって定義が与えられています。「一連のリファクタリングを行って、外部から見た振る舞いの変更なしに、ソフトウェアを再構築すること」リファクタリングとは、つまりソフトウェアの整理整頓みたいなものですね。スライドの左側の写真には、整理してこなかったので乱雑に道具が詰め込まれているだけの引き出しがあります。これを、引き出しとして機能させたままで、望む道具をすぐに探して取り出せるように整理整頓を続けていく。スライドの右側の写真では、引き出しは整理整頓されて機能的になっていますね。いった掃除や整理整頓のソフトウェア版がリファクタリングです。使った道具をすぐに片付ける、例えば使ったホッチキスをすぐに引き出しに戻すようなことを続けていれば。部屋は整理整頓が行われている状態が続き、その部屋、ひいてはその家で暮らしていく人たちは整った暮らしをしていける。恐怖に打ち克つための技術と道具を手に入れて戻ってきました。リファクタリングにおける「外部から見たときの振る舞いを保ちつつ」とは、「成功しているテストが成功しているままで」と言い換えられます。恐れていたのは、動いているコードが動かなくなってしまうことでした。いまや三種の神器を手に入れたことによって、動いているコードが動かなくなってしまう瞬間を、テストの失敗によって気づけるようになりました。「ニンベンの付いた自働化」で動いているから、人間が気付かなくとも機械が気付いて教えてくれるようになりました。動いていたコードが動かなくなってしまったら、バージョン管理システムで元に戻せば良くなりました。これは大きな進歩です。我々は安心してきれいな家に住んで、動作するきれいなコードを書けるようになりました。なるかというと、まだそうではありません。動作するきれいなコードを書いて、そのコードをそのままにすれば、動作するきれいなコードであり続けるでしょうか。コードに手を入れ続けなければ結局ひどいことになると、この講演でさんざん言ってきましたよね。きれいなコードを書けた時点で塩漬けにしても、結局周りのものが変わり続けて、「動作しないきれいなコード」に成り果ててしまうのです。ここまで言ってきたように、手を入れ続けられるコード、安心して積極的に変化し続けられるソフトウェアの方が、資産価値があります。ある時点で動作するきれいなコードであるだけでなく、ずっと動作するきれいなコードであり続けさせるとは、つまり変化し続け、対応し続けることです。物語はこれで終わりではないのです。大事なのは、学びを得て、フィードバックサイクルを回すことです。ソフトウェアは書いて終わりではなく、今日のソフトウェアはむしろ書いてからがスタートです。緑の星の象限に固定して居続けることはできません。周りのさまざまなものが変わり続けて、結果動かない方向に流されていくだけです。下りのエスカレーターに逆らうようにもがいて、動作するきれいなコードであり続けさせるためには、学びと開発のサイクルを健全に回し続けなければなりません。リファクタリングは1回で終わりではなかったのです。リファクタリング自身も、フィードバックを得て動作させ続けるプロセスの中にいなければなりません。コードを書いて動かし、フィードバックを得る。開発者のフィードバックだけでなく、チームの、お客様の、さまざまなフィードバックから学ぶことによって、はじめてソフトウェアは「比較的」正しいと思える方向に歩き始めます。大事なのは、フィードバックループを回し続けること、回し続けられるようにすることです。ここで、ようやくテスト駆動開発の登場です。フィードバックサイクルを回し続けられるようにする手段のひとつがテスト駆動開発です。フィードバックループを常に回し続け、テストとリファクタリングを両輪にして不断の改善を続けるためのプログラミングプラクティスがテスト駆動開発であり、その改善のサイクルがテスト駆動開発の本質です。テスト駆動開発には3つのステップがあり、それをサイクル状にぐるぐると繰り返します。サイクルと言われます。動作しない、おそらく最初のうちはコンパイルも通らないテストを1つ書く。先に1つテストコードを書きます。実装コードが既にあるかのように、こうなれば良い、こう使いたいと思うコードを利用者の視点からテストコードとして書きます。このときは動かないどころか、コンパイルすら通らないかもしれません。そのテストを動かすと、実装はまだありませんから当然テストは失敗します。テストが失敗すると、テスティングフレームワークは赤色でテストの失敗をプログラマに知らせてくれます。そのテストを迅速に動作させる。このステップでは罪を犯してもよい。次に、失敗しているテストを成功させるための必要最小限のコードを書いて、短い時間でテストを成功させることを試みます。このときはテストを成功させることのみに集中するので、コーディング上の罪を犯しても良いですし、多少の無理をしても構いません。コピーアンドペーストをしても良いとかですね。ほどなく、コードにはいろいろ直したい点があるものの、動く、つまりテストが成功するところまでやってきます。テストが成功すると、テスティングフレームワークは緑色でテストの成功をプログラマに知らせてくれます。テストを通すために発生した重複をすべて除去する。今度は、テストが緑のまま、つまり成功しているままでリファクタリングを行います。直前のグリーンのステップで無理をしてしまった結果発生した重複を除去したり、名前や構造をわかりやすくしたりします。テスト駆動開発におけるリファクタリングとは「成功するテストが成功しているままで、プロダクトコードやテストコードをきれいにしていく」ことです。リファクタリングが終わったらまたレッドのステップに戻り、テストを書いてレッドを見て、それをグリーンにして、グリーンのままリファクタリングして、というサイクルをぐるぐると繰り返します。サイクル、回転、それがテスト駆動開発です。サイクルはどのような軌跡を描くでしょうか。ふたつを重ねてみると、スライドの図のような軌跡を描きます。テスト駆動開発では第1のステップとしてまず先に失敗するテストコードを1つ書きます。第2のステップでは、失敗しているテストを成功させることのみに集中したコードを書きます。このときはコードのきれいさ等は特に考えず、最短時間でテストを成功させることのみに集中します。動作する」象限に遷移します。ここまで来ると、動くけどきたないコードが目の前にあります。第3のステップでは、テストが成功する間は改善の手を緩めずにリファクタリングを行います。動作する」象限に遷移します。動作するきれいなコードですね。緑のままでリファクタリングできれいにしていく。これがテスト駆動開発です。テスト駆動開発の各ステップの良いところは、矢印で表現できるくらい単目的であることです。動作しているコードをきれいにすることのみに集中します。矢印はすべて真っ直ぐで単目的です。短目的のタスクの組み合わせによってフィードバックサイクルが短時間で回るように設計されている点が、テスト駆動開発の良さであり強みです。サイクルを重ねたモデルを考案したのは10年以上前のことなのですが、日本全国で話しているうちに、いつしかこのモデルは黄金の回転モデルと呼ばれるようになりました。した軌跡を描いて回転している限りは、テスト駆動開発は大きなパワーを発揮し続けます。テスト駆動開発の回転がもたらすパワーは、矢印のどれかが傷つき短くなっていくことによって、だんだん減っていきます。3つの矢印のうちで、最も打たれ弱く傷つきやすい矢印はどれでしょうか。みなさんは、どう思いますか?一番弱く傷つきやすいのは、リファクタリングの矢印です。動作するきれいなコードへ至る2つのコースのうち、テスト駆動開発は基本的に青いコースを通っていました。きたない」コードの象限に沼地がありました。関してはまだ克服できていません。2つ目の感情、焦りやプレッシャーが手強い相手です。リファクタリングの時間が短くなったり、リファクタリングが先送りにされ始めます。リファクタリングの矢印は弱く、折れたり短くなったりしやすいのです。できあがり、付箋として壁に貼られます。「リファクタリング」という言葉には呪いがかかります。「リファクタリングという名前がついた付箋は剥がされることがない」という呪いです。着手されない、あるいは完了されない、という強い呪いです。そんな呪いがかかってしまうのでしょうかさきほど、リファクタリングを部屋の片付けに例えました。小さいリファクタリングのレベル、例えば「使ったペンを引き出しに戻す」程度の片付けなら数秒で終わります。部屋はだんだん散乱していき、しまいには部屋の掃除に数日かかるようになってしまいます。大ごとになってしまったリファクタリングには説明責任が発生します。リファクタリングはその定義上、機能を追加しないからです。リファクタリングに時間がかかればかかるほど、新たな価値に取り組むタイミングも延びてしまうからです。リファクタリングは、ソフトウェアの機能を変えないままで内部をきれいにしていく行為です。それゆえに「何も機能が変わらないのに2日使うの?」といった疑問を持たれてしまいがちなのです。独立した大タスクになったリファクタリングに理解を得やすいプロジェクトもあれば、理解を得にくいプロジェクトもあるでしょう。機能を変えずに、コードをきれいにすることのみに集中する。いった「技術的負債の返済」に理解のあるプロジェクトならまだ可能性がありますが、まだまだそこまで至っていない現場が多いものです。リファクタリングは大ごとになればなるほどさらに先送りになり、先送りになればなるほど呪いにかかって塩漬けタスクになってしまう。気がつけば荒れ果てた家に住んでいるということになってしまいます。こんなはずではありませんでした。リファクタリングを先送りにし続けると、リファクタリングの矢印は短くなり続け、しまいには「テストはあるけどきたないコード」をうろうろするだけになってしまいます。テストがあるだけまだ挽回のチャンスがありますが、もはやコードはきれいではなく、本来やりたかったこととはかけ離れています。弱々しい矢印であるリファクタリングを守るためには、「リファクタリングを独りにしない」ことが何よりも大事です。独り、つまり独立タスクにすると、呪いにかかってしまい、完遂できなくなります。すればよいでしょうか。リファクタリングを細かく分解し、日々のプログラミングの名も無き1ステップにしてしまえばいいのです。引き出しから取り出したホッチキスを使ってすぐに引き出しにしまうとき、わざわざ「ホッチキスを片付ける」とは言わないのではないでしょうか。しまうならば、それはホッチキス使用の名も無き1ステップです。必要十分な量のリファクタリングが行えるようになります。リファクタリングは一番弱々しく、呪いにもかかりやすいですが、一番重要な矢印でもあります。本来行きたい象限を指し示している矢印はリファクタリングだけです。リファクタリングを独立タスクにするのではなく、プログラミングの1ステップとしてサイクルの中に入れて保護しましょう。テスト駆動開発において、リファクタリングはテスト駆動開発を構成する小さいステップのひとつです。リファクタリングを独りにしないことは、実はテスト駆動開発のトリックであり、画期的な点なのです。リファクタリングを独りにしないことによって、テスト駆動開発の回転はふたたび回り始めます。ここからはテスト駆動開発のさらに外に視野を広げていきましょう。現代の開発を支えるのは、異なる半径の自己相似形のフィードバックループです。サイクルは、相似形のより大きな回転半径のサイクルに包まれています。Tests』、私たちはよくGOOS本と略すのですが、そのGOOS本から引用した図です(邦訳は『実践テスト駆動開発』)。ユニットテストのテスト駆動開発の回転の外側には、受け入れテストの回転があります。ユニットテストの回転は分単位で高速に回りますが、受け入れテストの回転は日単位でゆっくりと回ります。その外側にはさらに自己相似形のループがあります。フィードバックループを図にしたものです。プランニングからコーディングまで、回転半径の異なるフィードバックループによって構成されています。概ね自己相似形のループを重ねていく形になっています。様々なスケールにおいて、どうやってフィードバックループの回転を健全に続けていくかという問いが、ソフトウェア開発において非常に重要になります。学び続け、フィードバックサイクルを回し続けるのが生命線になるのです。フィードバックループには回転半径があり、回転半径ごとに狙いや得られる情報が変わってきます。現代では継続的デリバリのプラクティスが一般的になってきています。継続的なデプロイとデリバリを行い、実際のお客様に使ってもらうことによるフィードバックこそがもっとも「本物」のフィードバックだからでもあります。本日の講演はここからユニットテストにこだわります。ユニットテストにこだわって話すのでしょうか。それは次の理由からです。ついてはよくご存じだろうからソフトウェアの内部の質に関わるからテストピラミッドの土台となるからE2Eテストだけで開発が健全に回せるかというと、そんなことはありません。ここからはユニットテストのことをもう少し知り、考える時間にしたいのです。E2Eテストもユニットテストも共におろそかにできないのは、フィードバックの種類と量が異なるからです。Quality)へのフィードバックの量が変わってきます。スライドの図は、先ほど出てきたGOOS本に出てきます。この図は、テストのスケールと、外部の質、内部の質についてテストから得られるフィードバック量の関係を示しています。E2Eテストは外部の質へのフィードバック量が多く、内部の質へのフィードバック量は少ないですね。ユニットテストはその逆で、外部の質へのフィードバック量は少なく、内部の質へのフィードバック量が多くなっています。外部の質、内部の質とは何でしょうか。外部の質は利用時の品質に関わり、内部の質は中長期的な開発の継続性、健全性に関わることがわかります。前のページの図のフィードバック量から分かるように、ユニットテストは内部の質に強く関わります。中長期的な開発の継続性、健全性を損なうことにつながってしまう可能性が高いのです。ユニットテストが大事な理由のもうひとつは、テストピラミッドの土台部分だからです。テストピラミッドは非常に有名なモデルなので、この会場のみなさんにはもう説明不要かもしれません。提唱とされており、テストの理想的な割合について説明されています。全体の土台になり、健全なソフトウェア開発を支えます。いう3つの階層が出てきます。いう言葉が出てきました。