自動改札機の運賃計算プログラムはいかにデバッグされているのか? 10の40乗という運賃パターンのテスト方法を開発者が解説(後編)
9月12日から14日のあいだ、東洋大学 白山キャンパスで開催された日本科学技術連盟主催の「ソフトウェア品質シンポジウム 2012」。オムロンソーシアルソリューションズ 幡山五郎氏の講演「自動改札機ソフトウェアの品質向上の取り組み 厳密な仕様、もらさないテストを目指して」。この記事では、そのダイジェストを紹介しています。
本記事は、前編、中編、後編の3部構成です。お読みのページは後編です。
大規模なテストをどうやって実行しているか
続いて、大規模なテストについて。
1000万件のテストパターンを作っても、それぞれのテスト結果の正解を人手で作っていたら追いつきません。なので、別々に運賃計算ソフトウェアを作って、その答えを突き合わせてチェックしよう、という話です。
例えば、あるテストパターンがあって、2つの運賃計算のどちらの結果も同じなら正解だね、と考えるわけです。でも、両方とも間違えると困ります。
テスト対象となる実機用の運賃ソフトウェアと、検証用の運賃ソフトウェアは別のチーム、別のアルゴリズム、別のプログラミング言語で作ります。実機用はC++ですが、検証用はJavaで言語特有のバグをなくそうとしています。でも検証用のソフトウェアにはそんなに予算が掛けられず少人数で作っているので、実機用はどうやって作ったのか聞きたくなるのですが、そこを我慢して作る。
基になるデータベースも間違っている可能性があるので、検証用は別に手入力してデータのチェックも合わせてやります。
テストは100台くらいPCをレンタルして、がーっとやります。だいたい2週間から長いと3カ月くらい。このとき何に時間がかかるかといえば、間違った原因を探していくことですが、1000万パターンあると0.1%間違えても1万件とかになります。でも間違っているリストを見ると目黒ばっかり間違えていると、それで目黒のデータが間違っているというのが分かったりして。
間違いがあればその原因を解析しなければいけないのですが、検証用の運賃計算ソフトウェアが間違えることももちろんあるので、これをきっちり作らないと検証用のソフトウェアの方のデバッグをしているようになってきてしまいます。でもお客様には検証用のも合わせて2つソフトウェアを作るから費用を2倍にしてくれとも言えないので、頑張って作るしかないです。
ただ、検証用のソフトウェアは実機用よりも高速化しなくていい、実機用は約2MB以下のメモリで、50ミリ秒以内に計算しなければいけませんが、検証用はそうでなくてもいいですし、メモリもいくらでも使っていい。というわけで、実機用のソフトウェアはできるだけデータベースを使って計算量を減らし、検証用ソフトウェアは運賃計算ルールをきっちり使って作っている、というような違いがあります。
例えば、表参道で乗って池尻大橋で降りました、というパターンでは、実機ではここで乗り換えるテーブルというのがあって三角表になっていて、そこから運賃はいくらですと出してきます。
一方で検証用ソフトウェアは、まじめに路線図を見て経路をいっぱい出してきて、割引表なども見てひとつひとつの金額を計算し、一番安いのはこれですね、と出しています。検証用ソフトウェアはアルゴリズムが原則的なものを考えればよくて、変なチューニングも少ない。まじめに計算しているので、仕様の方におかしいものが見つかることもあります。
ここまでが実際の運賃計算プログラムのデバッグの話でした。
仕様書を形式仕様記述言語で書く
運賃計算の仕事をしている部署はみんなずっとこの仕事をやっている人ばっかりで、やはり属人性があって、運賃計算のルールがややこしすぎて新人がはいってこない。これが現状の悩みとなっています。
そこで私が一縷(いちる)の望みを託しているのが次の話です。仕様書をしっかり書きましょう、という取り組みをしたので、その話をします。
「形式手法」というのがあって、これは仕様書を数学チックにしっかり書こうということなのですが、日本語の仕様書があって、それを形式言語としてしっかり書きましょうと。イメージとしては、プログラムのような言語できっちり書いてあると。
日本語は整合性があるかなど専門家がしっかり見るしかないのですが、形式言語ならツールでいろんなチェックができますし、検証や証明もできます。
実験的なプロジェクトとして、仕様書を形式仕様記述言語で記述することに取り組みました。これによって仕様書が分かりやすくなったり、あるいは仕様書の問題点が見つけられればいいかなと。
形式仕様記述言語であれば、「ifなになら〜」と記述がプログラムチックになります。特徴は、まさに厳密な言語体系です。文法の誤りをツールチェックで可能、型チェックなどもできるので記述の誤解釈を起こしにくく、読み手の暗黙の知識を要求しないので新人が入っても対応できるようになります。われわれはVDM++を使いました。
日本語の仕様書を形式仕様記述言語にすると9400行になったのですが、そのうち1400行は日本語の仕様書に書かれていなかった用語の定義などでした。元の仕様書に一体何が抜けているのかということが分かって、社内にもインパクトがありました。
仕様書に書かれなかった言葉の定義だけでなく、複数の意味で使われている用語も多かったです。また、適応範囲が不明確なルールもあって、これまではルールがどこにかかっているかを改行の幅などで想像していたところも発見しました。
また、仕様の中でJR独自のところ、メトロ独自のところ、そして全体で共通なところなどの再利用可能な仕様書を構造的に作ることが将来的にできそうだということも分かりました。
先ほど、実機と検証用の運賃計算ソフトウェアを突合してテストする話をしましたが、仕様書そのものを実行して計算できたらいいなと思っています。
そういうことを考えて、VDM++で書かれた仕様書で計算できるようにする、ということにも挑戦してみました。そこで大変だったのは、仕様書にはどうやって経路を結ぶかというアルゴリズムは書いていないので、そのままでは計算できませんでした。結局、そのアルゴリズムは実機用のソフトウェアから持ってくるなど、少し手を借りれば計算できるようになりましたと。
で、計算させてみると64コアのCPUで80万ケースで5日間だったので速度的にはまあまあかなと。
将来的には、要求分析で書いていた仕様書を形式仕様記述言語で書いて、それがそのまま実行可能になることで、検証用ソフトウェアの開発コストが下がればいい、あるいはコストは下がらなくてもテストの品質が上がる、ということが考えられると思います。
会場からの質問
(質問) 仕様が難しすぎて新しい人が入ってこない、というのは、実は自分のところでも悩んでいる。この点に関する形式言語の効果はどうだったか。
効果はあると思います。これまで新しい人が入ってきても、運賃計算の仕様書を読むのは難しいし教えるのは大変です。用語集や事例集といった新しい人向けの資料を作っても、だいたい更新されなくなってしまって伝えきれない。それに最終的に仕様書には書いてない、といったこともある。
けれど形式言語なら、頑張れば読めるので分かる。本当にこうなればきれいな新人教育ができると思います。とはいえ、やはり仕様全部を形式言語で書くのは難しいと思うし、お客様に仕様を形式言語で書いてください、というわけにもいきません。なので、定義リストだけでも形式言語にすると。先ほどお話ししたように定義の抜けなどが分かるので、それだけでも効果がでると思います。
(質問)全網羅のテストパターンを最初に作る、というのは非常にハードルが高いのではないか?
ああいうプロジェクトを立ち上げたとき、社内でも「本当にできるのか?」と言われたことはあります。でもそれができたのは、やろうという強い意志を持っていたから(笑)、というのがあると思います。
まとめ
自動改札機のソフトウェア開発について話をしてきました。
自動改札機に対して実機レスでシミュレータでテストできるようになりましたと。
運賃計算では、全部を網羅したうえでパターンを絞り込みました。この方法は運賃計算が離散的だからできたので、連続的なものは簡単ではないですが、割り切ればできると思います。
また、2つの独立したソフトウェアでのテストもポイントだと思います。
仕様書テストでは、日本語での問題を見つけられたのが大きいところでした。
あわせて読みたい
[速報] ソースコードを表示するためのフォント「Source Code Pro」をアドビがオープンソースで無料公開
≪前の記事
自動改札機の運賃計算プログラムはいかにデバッグされているのか? 10の40乗という運賃パターンのテスト方法を開発者が解説(中編)