ソフトウェア工学に文句をつける

本稿ではソフトウェア工学の論文を1つ例として取り上げ、その内容に文句をつけたいと思う。取り上げる論文は、ソフトウェア工学の論文としてきちんとしたもので、ソフトウェア工学のトップ会議の一つであるISSTAで発表されたものである。

Milos Gligoric et al., Comparing non-adequate test suites using coverage criteria, ISSTA’13

PDF

論文の解説

ソフトウェアがちゃんとできているか、確かめるよくあるやり方はテストである。ソフトウェアにやってきそうな入力をいくつか用意し、実際にソフトウェアに入力してみる。そしてその結果をみて、ソフトウェアが期待通りに動くか確かめる。

ここで問題は、あらゆる可能な入力に対応するテストを用意することは、ほとんどの場合、不可能であるということだ。というのも、ソフトウェアが受け付ける入力の数は膨大なものになってしまうことが多いので。

というわけで、不完全なテストの「良さ」を評価するために「カバレッジ」という概念が登場する。ソフトウェアテストのカバレッジの概念は多数提案されていて、例えば

  • コードカバレッジ:テストによって実行されるコード(例えばプログラムの文)が全体のどれだけか。この論文ではステートメントカバレッジと呼んでいる。
  • ブランチカバレッジ:プログラムの中に含まれる分岐のうち、どれだけが実行されたか
  • パスカバレッジ:プログラムの中に含まれる実行パスがどれだけ実行されたか

などなど。これらのカバレッジ基準によって、テストが評価できる…わけだが、評価基準がたくさんあるので、評価基準自体の評価が必要になる。それをしましょう、というのがこの論文。ただし、カバレッジ基準が完全に満たされている(100%のとき)場合は先行研究があるので、基準が完全に満たされない場合を考えた、というのがこの論文の新しさ。カバレッジ基準が100%満たされることはめったにないので、この論文のやっていることは意義が大きい。

さて、どのようにカバレッジ基準の妥当性を評価するか。テストは究極的にはバグを見つけるためのものなので、そのテストがバグを発見できる確率とカバレッジ基準の達成度合いの相関を見る。バグは人為的にコードをランダムに変化させることにより生成する。テストによるランダムな生成によるバグの発見率と、人間が作るバグの発見率は、相関していることが知られているので、このような評価で問題ない。

さて、この論文の結論は本稿の目的とはあまり関係ないが、一応書いておくと、ブランチカバレッジが、他の複雑な基準を押しのけて、一番良い。ただし、テストが十分行える状況ではAIMP (acyclic intra-method paths)カバレッジという基準が良いらしい。

文句をつける

さて、この論文、動機づけも明確で良いし、実験もきちんと行われていて興味深い結論を引き出している。考察も示唆的だと思う。良い論文だと思う。

それでも文句をつけたくなる。

  1. 理論的な基盤の欠如:この論文の結論の正当化には、直感に訴えた議論はあっても理論的なものはない。
  2. 特定のデータセットやツールに依存している
  3. 特定の言語(Java)とプログラミングパラダイム(オブジェクト指向言語)に限定された研究である

ランダムなバグを検出するのにどのようなテストを行えばよいか、というのは原理的には純粋に理論的な課題なはず。もちろん実際は難しいかもしれないが、近似的な議論とか、なにかできないのだろうか。大量なデータを用いた経験的な研究を行うのが最近のソフトウェア工学研究のトレンドだが、理論的な正当化が不十分であるように思う。そして、理論的な正当化が不十分であるために、次に述べるように、結果の一般性に疑念が生じる。

2.は言いがかりのように聞こえるかもしれない。実験をする以上、何かのデータセットやツールに依存せざるを得ないのは明らかではないだろうか。しかし、ソフトウェア工学分野の研究では、比較を公平にするためもあるのだろうが、同じデータセットやツールが複数の研究で繰り返し用いられている。つまり、研究分野自体が特定のデータセットに過学習しかねないように思う。

さらに言えば、現在のソフトウェア工学のほとんどがJavaプログラムを対象にしている(CやC++が対象になることもある)。これは不健全な状況だと思う。別のプログラミング言語やパラダイムが主流になったとき、またすべての研究を一からやり直すのだろうか。

ではどうすればよいか

あまり大した提言はできないのだが、まず大量データを解析して経験的に結論を下すだけではなく、なぜそれが成り立つか、理論的な考察が必要だ。理論的な考察があって初めて、得られた結果が一般性を持つのかどうか、異なったプログラミングパラダイムに適応可能か、といったことが分かるはず。

もう一つは、Javaだけではなく、異なった言語・パラダイムの研究を行うべきだということ。静的型付けがあるのとないのとではどう違うか。型推論はどのような影響を与えるか。オブジェクト指向と関数型言語ではどう違うか。などなど。

まあ、お前がまずやれ、という話になりそうだが…