node.js + mocha に限らずウォ…ちょ、まてよぉ

言葉が思い出せなくてちょっと弱った。

一つ前で困っていた WALLABY.JS なのだが、サイトを訪問してみたら、どうやら商用製品らしい。うーん、ありがち。商用製品だから避けたい、ということでもないけれど、ただワタシがやってるのは「所詮趣味の延長のお遊び」なので、それにかけるコストでもないかなぁ、と。あと商用製品だと今みたく「遊びなので」でない業務で使うような本気用途なら、「本気の評価検証」作業がどうしても必要だよね。(これはフリーでも本質は一緒なんだけど、「お金を払うからには」となると少し本気度が上がらざるを得ない。)


ちょっと今回したい話の前に、「カバレッジツールがやっていること」のおさらいをしておく。

テクニカルな意味では、これは「言語によって全く異なることをする」。具体的に言えば、「言語(もしくはその言語の開発ツール)が提供するプロファイラ・トレース API を使って、全コール・フローを追跡する」というのが基本。

Python の場合は、Python 利用者がいつでも誰でも使えるように直接これが公開されている。いわゆる「スクリプティング言語」がこうしたものを公開するのは、Unix 文化では boune-shell から既にある「伝統」である。大昔初めて perl を知ったときに、デバッガが内蔵されていることにはいたく感動したものである。

対して、C/C++ の場合は、「公式な手段は C/C++ 言語そのものには内蔵されていない」ので、コンパイラベンダーがコンパイラに「「追跡コードを仕込む」拡張を仕込む」ことによってこれを実現する。つまりトレーシング目的専用の生成物をコンパイラが生成出来るようになっている。(簡単に言えば「プロファイル・トレースを仕込んだ版の別 EXE (等)を作る」ということ。) 当然これは「開発環境によって違う」ことになるのだが、ただ最近はメジャーな開発環境がほぼ二択(GCC or MSVC)になりつつあるため、昔ほどは苦労はしなくなった。(かつては Unix を使っていてすらも Sun の K-R C、Sun の ANSI C、GCC の古いの、GCC の新しいの、みたいに3つ4つくらいは普通に共存させるのが当たり前だったので、それはもう「都度都度違うこと」をしていた。ついでに言うと、ベンダによるこの仕掛けがない場合でも、「ソースコードとの合致」はアセンブラのレベルでは常に(OS のサポートにより)可能である。「C/C++ソースコード」との対応が、コンパイラの助けがなければ出来ない。)

ただ最終的にはカバレッジツールは、どんな言語相手であっても、「ソースコードとトレースの合致を行い、それを可視化する」ということがひとまずのゴールである。なのでそうしたデベロッパツールの利用者には、どんな言語のものでもだいたいは同じように見える。つまり「コード全行と、通った/通ってないがわかるハイライト」のペアで構成される UI になる。(そしてその「可視化」は、「カバレッジ計測」のゴールであるところの「網羅率」を計算して出してくれる。)


おぃ、ちょ、まてよぉ。

今の話は「自動で」やる場合の話。これが「出来て当たり前」になっている現代では、出来ないことで「やるかやらないか」の二択になる…、のかよ、本当にそうなのか? ということを、「思い出した」という話です、今回の話は。

長らくやってなかったので、自分でもすっかり忘れていたのだが、そもそも「ウォークスルー」という優秀な「道具」があるではないか、と。実際ワタシが今作ってるヤツなんか、規模が言うても一人でずっと管理出来るほど「極小」のプロジェクトなわけなのよ。だから「カバレッジツール」に頼ればそりゃぁ「楽」で「一撃」だろうけど、一つ前に書いた通り、ワタシがカバレッジツールに期待していることはまさに「ウォークスルーに求めること」の半分そのもの、なんだよね。やりたいことは「フローの点検」で、カバレッジツールが「分岐を強調してくれる」ということを喜んでいただけなわけだ。

分岐だけを洗い出すんであれば「ウォークスルー」そのものではなくその一部ということにはなるが、ともあれ、もっとも直裁的には、「とにかく全 function の一覧を作り、全 function 内の分岐を全て書き出し、これを表に仕立て上げる」。こんなんは excel でもなんでもいいのだ。そしてこの表に「到達・未踏」のチェックを書き込めるようにしておく。(ちなみにワタシは excel だとダルいので、多分 reStructuredText とか org みたいなのでやるつもり。)

あとはこの管理表を完成させることを考えるわけだが、「通った」の検出はこれはもう「ほんとにウォークスルー」的に机上でやるか、もしくは「一時的に」(javascript なら) console.log を仕込むことで検出すれば良いであろう。この管理表が xUnit (今の場合は mocha) のテストコードとリンク出来れば理想だ。それがいいね。(だったらなおのこと excel でない方がいい。)

うん、もういいや、それで行こうっと。

皮算用、以上。


「ウォークスルーなんて時代遅れなこと、未だにやってるわけ? 考えるわけ?」と考える人がいるなら(というかほとんどがそうだろう)、たぶん職業プログラマの経験が少しもないか、もしくは新興のベンチャー企業の方々なんであろう。実際一定以上の経験年数の者なら、大抵一度くらいは経験してるんじゃないかなと思ってる。「今ではほとんど使われない」としても、その価値を知っている年長組の誰かが口にするくらいのことは、結構あるんではないのかな?

実際「巨大な予算をかけて作られる基幹系のソフトウェア」なんてのは、「贅沢に時間をかけてテストする」のが「当たり前」なので(普通「作りこみ」時間を3ヶ月とすると、テストは1年とか(設計が2年とか))、その中では、昔は本当に「ウォークスルーテストをするのが当たり前」だった。ついでに言えば、「レビュー」は、設計レビュー、ソースコードレビュー等々含め、本当に膨大な時間を取る。作ってる時間3ヶ月と言ったが、実際本当に「ソースコードを書いている」時間なんて、その1/3 にしかならないのが普通で、ほとんどはレビューの時間だった。

で、それをしていた当時のワタシというのは 25、26歳の頃なので、まぁ言ってみれば「血気盛んで怒れる若者」でもあり、「それはオカシイ!」みたいに思うことも結構あったりもしたんだけれど、ただねぇ、ワタシはどういうわけか、「ウォーターフロー開発」だとか、「ウォークスルーテスト」「ピアレビュー」といった開発スタイルに疑問を感じることはなかったんだよね。レビューで叱られてヘコんだりすることも多かったけれど、ただ、どれも若い私にとって新鮮で、楽しかったのだ。

具体的に「ウォークスルーテスト」を当時どうやっていたか、というのはこれは:

  1. ソースコードを印刷する。巨大なプリンターで印刷する巨大な紙。自担当分は一つ当たりだいたい5cm~10cmの厚さになる。
  2. これを、先輩(だいたいは2~3年上の者が担当)と「読んでいく」。
  3. これは本当に「一行ずつ」意味を二人で確認しながら「読んでいく」のだが、これが結構楽しい。
  4. 通過(読んだ)した行に、マーカを引いていく。
  5. 分岐が現れたら、まぁなんかしらのストーリーをこじつけることにはなるけれど、「こっちに分岐したとしたら」として読んで、分岐する。
  6. これを分岐分繰り返す。(なので分岐の妥当性はこのプロセスで検出出来ることも多い。)
  7. サブルーチン呼び出しのようなものについても、逐一「呼び出したぞー」とソースコード上をジャンプ(紙なのでね、めくるんだよ)して、同じ要領でマーカを引いていく。

こうして「全行にマーカを引く」。これが「カバレッジ100%」ですよ。そして、そうした「ビッグバジェットプロジェクト」では(でなくてもだが)「テストのエビデンス」が非常に重要視されることになるので、この「ウォークスルーテスト」の結果は、(デカくてかさばろうが)製品納品後も保存される。

で、XP プログラミングを初めて知ったときにはね、「すげー新技術キャー」と熱狂しちゃって気付かなかったんだけれど、よくよく考えてみれば、XP プログラミングが推奨する「ペアプログラミング」ってさ、この「埃がかぶった旧石器時代技術」であるところの「ウォークスルーテスト」がもたらしてくれる効果と、本質的なところでは「全く一緒」なんだよね、今にして思えば。「そこで得られる楽しさ」についても同じ。

まぁ「カバレッジツールが使える」のにあえてやるべきものだ、というほどのものではないのかもしれないけれど、なんだろうなぁ、今の若い人には、一度体験してみたらいいんじゃないのかな、と思う。「一緒にウォークスルーして欲しいんですけど」と、気の合う先輩に頼んでみる、とかね。多分かなり新鮮な驚きがあると思うよ。