2019年1月24日木曜日

毎月勤労統計のプログラムに関する問題は、プログラミング言語が古臭いことではなく、テストをまともにしなかったこと

このエントリーをはてなブックマークに追加
Pocket

経済学者を名乗る池田信夫氏が、毎月勤労統計の統計処理が適切に行われなかったことに関して、「COBOLで書かれた特殊なプログラムなので高齢者しか読めず、そのミスがチェックできな(かった)」と主張しているのだが、ソフトウェア開発の観点から問題があるので指摘したい。コードレビューと言う観点から言うと、古臭いプログラミング言語の方が有用だったりするし、システムと言う観点では動作テストをまともにしていなかったことの方が問題である。

1. コードレビューよりも動作テスト

コードレビューと動作テストは排他的ではないのだが、コードレビューは正しく動作させると言う意味では生産性が低いことが知られており、二択であったら動作テストをすべきなのは議論の余地はない。もちろん、動作テストと言ってもエラーで異常終了しないと言う意味ではなくて、出力や動作が適正であるかの確認。

動作テストがしやすいコードとしづらいコードがあるのだが、毎月勤労統計のプログラムのようにデータを入力して数値を返すようなシステムであれば、ある入力値に対する出力値が正しいか付き合わせれば済むので、もっともやり易い部類だ。プログラミングを行う者と、テスト・データとそれを正しく処理した結果を作成する者は同一で無くてよい*1

COBOLプログラマの不足によりダブルチェックが不能であったことは、対応不可能な問題ではなかった。数千件のデータでも用意して、もっとも基本となるテストを正しく実行していたら、今回の問題は事前に発見できていた*2。厚生労働省は明らかに間違った統計処理を行い続けていたので、まともにテストをしなかったのは確実だ。

2. 毎月勤労統計の計算はテスト駆動開発に向いている

何かの変更のたびにテストを繰り返すのは手間隙と思うかも知れないが、作業手順を確立すればそうでもない。

テスト駆動開発(TDD)と言う単語が広まったのは21世紀になってからで、古いCOBOLのシステムで使えるテスティング・フレームワークがあるかはわからないが、毎月勤労統計であれば、グラフィカル・ユーザー・インターフェイス(GUI)のテストをするわけでもないので、特殊なフレームワークなしでもテストを自動化も可能だ。テスト・データを作るときに、テストで比較する正解の値をせっせと手計算することにはなるので、手計算できるようにテスト・データの桁数などを調整する必要*3はあるかも知れないが、ちょっとした工夫で乗り切れる。

層化サンプリングの方法と言うか配分を見直したり*4、サンプル替えの補正を行ったりするような変更*5の後にもテストはするべきだし、何かで予算がついて外部発注する場合も受け入れテストは必要になる。この手の統計はぱっと見で問題が生じているかわからないわけで、必要性と言う意味でもテスト駆動開発が向いている。

3. 業務が属人化し曖昧仕様になっていた可能性

このように説明すると、毎月勤労統計で、費用対効果が大きいテスト工程を省いたか、手を抜いたのを疑問に思うかも知れないが、現場主導で業務が属人化しているときはテスト駆動開発は困難になる。

テストの合格基準は仕様に沿って決定されるが、厚生労働省や調査に協力する都道府県の間で、調査方法が明確に共有されていたのか怪しい。層化サンプリングの方法や逆数表などは公開されており、調査方法を共有する必要性は理解されていたと思うが、法律で定められた手順を逸脱しているところ、再集計するために必要になる頻度表を扮しているところを見ると、調査マニュアルにしたがって作業が進んでいると言うのではなく、現場で何となく合意した変更が調査マニュアルに反映されていた可能性が高い。曖昧仕様はテストパターンの作成を困難にすることは、どこの職場でもあることだ。目玉焼きを知らない人は、目玉焼きが綺麗に焼けたか判定することはできないのだ。毎月勤労統計に関しては曖昧仕様でテスト駆動開発ができていない蓋然性は高く、少なくともそれを防止する体制にはなっていなかった。

4. TDDの導入で、仕様が明確化され、イカサマが難しくなる

仕様を詰めてテストパターンを整備することが、従来プログラムの修正と再集計の後にすべき施策となる。テストパターンの作成のために仕様が明確化されることこそが、テスト駆動開発の最大の利点とまで言う人もいる*6が、実践としてはテストパターンの作成を義務とすれば上手く回っていくと思う。仕様が明確化されれば、属人化の多くは解消されるし、(意図的か議論になっているが)イカサマもしづらくなる。こういう分けで、ソフトウェアの品質を上げるために必要なことは、プログラミング言語やミドルウェアを更新が第一と言うわけではない。ツールで解決できる問題とそうでない問題があり、今回はそうでない問題の影響の方が大きい*7

なお、仕様を固めてテスト・パターンを整備するのには、主観的に費用対効果に見合うとは言っているものの、それなりの工数がかかるもの。今の厳しい予算で担当者1名と言われる体制では、場当たり的な対応しかできないかも知れない。世の中、先立つものが重要である(´・ω・`) ショボーン

*1毎月勤労統計調査を巡る不適切な取扱いに係る事実関係とその評価等に関する報告書」には以下のようにあるのだが、テストデータとそれを正しく処理した結果を作成するためにはCOBOLの知識は必要ない。事業所を層化しつつ労働者の平均の賃金を求める変則的な層化サンプリングの知識の方が重要である。

毎月勤労統計調査に係るシステムのプログラム言語はCOBOLであり、一般的にシステム担当係でCOBOLを扱える者は1人又は2人に過ぎなかった。このため、一般的にシステム改修を行う場合はダブルチェックを行うが、ダブルチェックができない場合も多かった(平成15(2003)年当時はCOBOLを扱える者は2人いたが、それぞれが別の仕事を分担して処理していたため、当該者同士でダブルチェックをするようなことはなかった。)。

*2異常系や境界値のテストをしなくてよいという意味ではない。

*3本番データでは600万人分ぐらいの給与額を足しているので、部分的にも桁数が大きくなっている可能性がある。人数ではなくシェアをかけてから合算したり、1000円単位にしているのかもだが。

*4産業構造の変化のためか、極端に母集団からして数が少ない層があるようだ。つまり、層化サンプリングの教科書的には、適切な層化になっていない。なお、階層ごとに割り当てる標本サイズをハードコードする設計はどうなんだと思うかも知れないが、層ごとに割り当てる数を別のファイルなどに保存していても、新たな割当数に応じたテスト・パターンを用意するべきであろう。

*5「毎月勤労統計のサンプル入れ替え方法とギャップの補正方法の今後の方向性について」議論されていたはずだが、何か決まっているかは確認しなかった。

*6もちろん、半分は冗談であろう。

*7今後のことを考えると、プログラミング言語や開発環境を現代的にした方がよい。COBOLと言うだけで避けられる傾向があるし、TDDのフレームワークなども無さそうである。

1 コメント:

Hyozo さんのコメント...

理屈はわかるのですが、役所の中でプログラミングに精通した人材がごく限られている中ではその理屈自体を理解できる人も少なく、実際問題としてCOBOLを知らないことが阻害要因になった可能性もあるのではないのでしょうか。悲しいことですが。。。
また、テスト駆動開発という手法も、何かと注目を浴びやすくどんな些細なミスも叩かれる厚労省では、政治的に見て勇気のいる手法ではないかと思います。

コメントを投稿