原則:入力データや連携データをバリデーションチェックする。
――という処理が必要になる。
事例:無限ループ
33: //バリデーション
34: let errmsg = '';
35: if (principal <= 0) {
36: errmsg = '元金に正の整数を入力してください.';
37: } else if (rate <= 0.0) {
38: errmsg = '利率に正の数を入力してください.';
39: } else if (border <= 0) {
40: errmsg = '境界値に正の整数を入力してください.';
41: }
42:
43: if (errmsg == '') {
44: //複利計算
45: let deposit = principal; //預金額
46: let year = 0;
47: while (deposit <= border) {
48: deposit *= (1 + rate);
49: year++;
50: }
51: //計算結果
52: ret = year.toString() + '年目に ' + parseInt(deposit, 10).toLocaleString() + '円';
53:
54: //エラー・メッセージ
55: } else {
56: ret = errmsg;
57: }
58:
59: //結果を表示する
60: document.getElementById('deposit').innerHTML = ret;
61: }
元金がある額に増えるというのが大前提でプログラムを作っているから、金利 rate はプラスの数値でなければならない。
だから、金利 rate がプラスの数値であることを、whileループ に入る前に if文 を使ってチェックしている。同様に、元金、境界値もチェックしている。
プログラムの利用者は、開発者が想定しないようなデータを入力することが多い。プログラムの使い方に慣れていない場合は、特にそうだ。
また、悪意をもって想定外のデータを入力し、プログラムを停止させようと目論む攻撃者もいる。
だから、入力データは、まずバリデーション・チェックしてからプログラムに渡さなければいけない。
また、経験豊富なサービス技術者であれば、入力バリデーションを行っていないことに気づいた時点で、そのプログラムを読むことを止め、開発側に是正指示を出すことだろう。プロは、時間を無駄にしないものだ。
応用:システム連携
プログラムは常に改良されている。WebAPIやシステム連携I/F仕様書に書かれているデータが、かならずしも送られてくるとは限らない。プログラムの修正に仕様書が追いついていないことがあるからだ。
これが仕事なら、責任は相手側システムにあるのだが、責任追求は上層部の仕事で、現場は仕様外のデータが送られてきて自社システムが止まったら被害を受ける。だから、受信データのバリデーションチェックを仕込んでおくに越したことはない。
同様に、データベースに書き込むときも、書き込む前にデータのバリデーションチェックをしよう。データベースによっては受け付けられない文字コードがあったりするためだ。
コラム:チルダ問題
たとえば、「東京駅~横浜駅間」のように使われる ~ だが、UNICODEでは U+FF5E 、俗に波ダッシュと呼ばれる。
一方、半角チルダ ~ の全角文字 〜 というものもあり、こちらは U+301C である。
同様のことが、ダッシュやマイナス、ハイフンについても言える。
経験豊富なテスト技術者は、こうした揺らぎのある文字を文字列に混ぜ込んで、嫌がらせのように入力テストを行うものである。その試練に耐えられるよう、しっかりバリデーションチェックを組み込んでおこう。
たとえば、割り算の割る数(除数)は0であってはならない、平方根に渡す値は0以上の数でなければならない‥‥等々、算数や数学の世界には、定義域がある。証明問題で言えば仮定。仮説の検証作業においても、かならず前提を置いて作業を始める。