Webサービスを提供している会社で、今時、DevOpsや自動化テストを整備していないところがあるとしたら、そのプロダクトはほぼ100%、迷走を続け、不具合を出し続けて、利用者に迷惑をかけまくってるはずで、そこでは、『7つの習慣』の『木こりの挿話』の「刃を研いでいる暇なんてないさ。切るだけで精一杯だ」というのとほぼ同じセリフが繰り返されているはずだ。
一つ前のどうしようもない技術者が集まっていた現場でも、新規開発時、「まず環境整備」ではなく、「まず見えるところの実装」「そのうち環境整備」「まず一本、木を切り出す」だった(環境整備のブランチは勝手に消されていてね。リーダーも最初にOK出してたのに、日和って削除を認めてたんだよね)。
どうなったかというと、「現在可能な環境整備による制約」を確定しないで行き当たりばったりに実装しため、「ローカルで実行できない構成」になり、クラウドの開発環境を取り合い、無駄な待ち時間が積み上がり、開発が滞り、無理やり実装を強行して不具合が出まくり、ボード、ビジネスメンバーから罵声が飛び、技術者たちは嫌気がさし、という「だめプロダクトを大きく育てる好循環」がアジャイルでぐるぐる回り続け、お披露目の日が来て、クライアントの前で大失態、というありがちなパターンに陥ったとか。
自分がその現場に入った時、前バージョンが陥っていたこのパターンから脱出するために、半年以上の時間をかけて、新機能を追加しながら体質改善をしたっていうのに、組織や技術者(前バージョンの初期メンバーの出戻りがね)が反省し、学習し、マインドを変えなかったから、同じパターンに陥ったわけだ。
システムの不具合の99%は、技術者の準備不足から生じる(関係者間合意内容の確認を含めて)。
準備していないから不具合が発生するのだから当然だ。
プログラミング初心者は目の前の処理を書くことだけしか考えられなかったり、Webページ紹介と早組みがプログラマの能力の全てだと勘違いしている中級者と、それを無批判にありがたがる非技術者という問題が解決されない限り、日本のWebサービス事情は変わらないだろう。
本当にちゃんとした技術者は、目の前のコード一つの裏で、いろんな準備や仕掛けを施している。
一見、激しく木を切る(実装をしている)ところをアピールする手合いの中級者が組んだプログラムと同じに見えるかもしれないが。
プロ棋士が一手に1時間以上かけたりするのは決してサボっているわけではない、のと同じだ。
木こりの挿話と合わせて紹介されることの多い、リンカーンの「もし8時間、木を切る時間を与えられたら、そのうち6時間を私は斧を研ぐのに使うだろう」という言葉がある(これ、本当にリンカーンが言ったかどうかはわからない。けど大事なのは「誰が言った言葉か」ではなく、内容だと思う)。
正直、8時間に対して6時間だと、斧を研ぐだけにしては時間をかけすぎな気はしないでもないが、搬出手順やそのためにどこから切り始めるかなどの戦略検討を入れれば、むしろ少ないくらいかもしれない。
システム構築の成否は、80%は事前準備(関係者合意、環境整備、アーキテクチャ設計)、足場準備(自動テスト、DevOps)という、機能実装ではない部分にかかっていると思う(この事前準備や足場準備のための知識習得という、さらにその事前準備もかなり大事なので、全部合わせると機能実装部分のインパクトはさらに減る。技術者は一生勉強、というのがまさにこれだ)。
ちょうど、舞台が脚本、制作、稽古などで8割方決まり、当日の役者の働きだけでは全く挽回できない、と言うのに似ている。
「刃を研いでいる暇なんてないさ。切るだけで精一杯だ」という技術者がいたら、「刃を研げないものは切るな」「刃の研ぎ方を知らず、知ろうともしないものは切るな」と通告し、追い出すべきだ。
既に見た通り、邪魔で無駄で迷惑だからだ。
こういうタイプの技術者がメンバーに混じっているとチームの士気が落ちるし、リーダーがこれだと言わずもがなだ。
もしあなたが経営者で、「うちのシステム、不具合が多いんだよな……」と思っているなら、あなたが頼りにしている『できる技術者』こそが、諸問題の根源であり、疫病神である可能性が高い、ということにここで気づいてもいいと思う。
本当にできる技術者なら、不具合の連鎖は最初から起こさないよう準備するし、起こったとしても早期に断ち切ることができるはずなので。
で、冒頭の自動化テストに戻る。
「TDDなんて意味ない」とか「テスト仕様書書いて手動テスト」とか言ってる技術者が思いの外多くて驚いているのだが、日々、猛烈な勢いでテスト仕様書が積み上がっていく今時のシステムで、仕様変更のたびに既存の仕様書をメンテナンスし、増える一方の手動テストを全部行うことが不可能なことが明らかで(だからこそ自動化テストの仕組みが整備された)、そのうち仕様書が現実と乖離し、全テストが実行できないので新機能分だけのテストでお茶を濁して、出荷検査を誤魔化し、以前動いていた機能をぶっ壊したバージョンをリリースしてしまうとか、ほんと、ダメな現場ではほぼ確実にやらかしていることだろう。
それは持続不可能だ、と結論が出ているのだから、当たり前の話なのだ。
何も考えず「テスト仕様書書いて手動テスト」を提案する技術者は、残念な技術者だと言わざるを得ない。
で、「TDDなんて意味がない」という技術者。
どうも話が通じないな、と思う部分がやや共通してある。
自動化テストとユニットテストが同値である、と勘違いしているような気がする。
自動化テストの例示では、まず間違いなくユニット(クラス単体、関数単体)テストを、xUnitというフレームワークが使われていて、それ以外の例示がないからなのかな? と思わなくはないのだが、自動化テストは出荷時に自動で行うテストであって、自動化テストの解説時には規模が小さくできるからユニットテストが一例として利用されるわけで、それはユニットテストは自動化テストにほぼほぼ包含されるというに過ぎない(カバレッジが100%になることはない、と、カバレッジはあげればあげるほど価値があるという神話があるが、ユニットテストに関してはどう見ても明らかだろ、という枝葉末節部分についてまで毎度自動テストを行う必要は、もちろんない)。
自動化テストは「そのモジュール出荷時に自動でやりたい、できる」テストのことだ。
そして、出荷時にやるべきテストというのは、「そのモジュールが対外的に約束している機能が正常に動作し、今回の修正でぶっ壊れていない」ことを証明するためのテストで、APIサーバならAPIの出入り、フレームワークならフレームワークが提供する機能といった、シナリオレベルのテストも、当然含まれるはずだ。
で、どうしても自動化できないテストは、やむを得ず手動で行うわけだが、ここで大事なのは「プログラムを組む時には、自動でテスト(検証)できるように組まなくてはならなず」、プログラムをスパゲッティに組み上げてから「どうやってテストしようか」って考えてもテストの実装は困難で、誤魔化しのテストをでっち上げる羽目になって、不具合をなくす目的を果たせない、実質何のテストもしていないテストになって、ただメンテ対象を増やすだけになる。
そして、多分、そうなっている現場は多いと思う。
これをもって「TDDは意味がない」と結論するのは浅はかで、これが意味する事実は「意味のあるTDDを理解できない技術者は意味がない」というに過ぎないのだ。
この全てが、機能を実装する「木を切る」という行為ではない、「刃を研ぐ」事前準備であり、これがシステム開発、プログラミングの、大きく語られないが一番重要な点だ、ということだ。
ダメな現場からヘルプで呼ばれるようになって、この辺りの共通点を身を持って体験することになったわけだが、驚くことにそのどの現場にも、勉強会に熱心に通い、Webページを調べまくっている技術者が少なくなく在籍していたりする。
なのになぜ?
と考えて、そのほとんどが、ここでいう「木を切る技術」にばかり注目して、「刃を研ぐ」ことに無関心だ、ということに気づいたので、ここに書いてみた次第だ。
多分、アメリカなどで「正規の教育」を受けていれば、ある程度は触れられているはずなのだが、日本ではね……。
ましてや数ヶ月の「オンラインプログラミング講座」では。
自力でたどり着ける人は少ないのだろう。
そういうことだと思う。
これでダメプロジェクトが一つでも減ってくれたら嬉しいんだけど、ここで言っていることはそれぞれの現場でも話してきて、それでも理解できない技術者が相当数いるということなので、万に一つでも、という期待感しか持てないのだよな。