事故が起きるまで
ソフトウェアの不良によって引き起こされる事故も、交通機関の人身事故も、基本的に原理は同じです。だから、同じ言葉で「事故」と言います。
原理が同じと言うことは、当然、抽象化されたメタな仕組みも同じと言うことです。だから、この原理を知っておくと、世の中のあらゆる事故について、正しく分析し、正しく対応することが可能になるというわけです。
…事故だけですよ?事件は知りませんよ?
ただまぁ、私は今のところまだIT屋の人間ですので、ソフトウェア開発を例にして、そこから派生させていく説明しかできません。
ソフトウェア開発における「バグ」とはなんですか?
と聞かれて正しく答えられる人は一体何人いるでしょう。
似た言葉に、エラー(error)や不良、故障などと言った言葉もありますが、これらとは意味が異なるのでしょうか。それとも同じ意味でとらえるべきなのでしょうか。
意外とこの辺りがあやふやなままエンジニアリングをしている人が多いみたいで、たまに会話がかみ合わなくなることがあります。コミュニケーションにおいて最も恐ろしいのは「あやふや」な言葉を使って、相手の読解力を乱してしまうことです。
少し脱線しますが、たとえば、
「これ、きれいに直しておいて!」
と言って指示されたとき、「きれいに」とは具体的にどういう状態を指しているのでしょうか。10人が指示し、あるいは10人が指示され、皆が皆、一様に全く同じ状態を思い浮かべることができるでしょうか。
ビジネスコミュニケーションで、"形容詞"を乱用するのは本来御法度です。一般的には「ビッグワード(big word)」と呼ばれていますが、これらを乱用されると、表現と読解に幅ができて、結果がブレやすくなる問題が多発してしまいます。
このように、「あやふや」と言う状態を普通だと思って、放置しておくのは辞めた方がいいと思います。特にITの現場は、基本的に0と1の世界、ロジカルな世界です。日本語であやふやなままにした指示、命令は、必ずプログラムで異なる翻訳をされてしまいます。
話は戻って「バグ」についてですが、まとめて表現を整理してみましょう。
■ 間違い/誤り
誤った結果を生み出す、人間の動作。ミス(miss)/エラー(error)とも言う。「ヒューマンエラー」と言うコトバに代表されるように、エラーは機械ではなく人が起こすモノである。
■ 不良/欠陥
要求される機能に対して、処理の不正を引きを超すモノ、または要因。バグ(bug)とも言う。バグは、エンジニアが誤ったコードを書いたり、変なデータを定義したり、つまりは「間違い」によって作られるモノである。
■ 故障・事故
ソフトウェアの期待される成果、サービス、および結果からの逸脱。アクシデント(accident)とも言う。簡単に言うと、対象が期待しない動作をすること。それによって被害を受けること。
ということです。これらには一連の関係性があることがわかりますでしょうか。つまり
人間は「過ち(エラー)」を起こす。
エラーによって「欠陥(バグ)」を招く。
バグが動作することによって「故障」が引き起こされる。
ということです。自動車事故も基本的な原理は同じです。
人間は「過ち(ルール上認められない操作)」を起こす。
過ちによって、自動車に「想定されない挙動」を招く。
想定されない挙動によって「人身/物損事故」が引き起こされる。
起点はすべて「人間の過ち」です。ソフトウェア開発において、バグを混入させるのも「人」です。それを発見できずに世に送り出してしまうのも「人」です。
バグは、常に人の「過ち/誤り」が産み出すものだと言うことを覚えておいてください。
「故障」を発見する方法
ITがここまで世に深く浸透した理由の第一義は「自動化」でしょう。それは間違いないと思います。より豊かになるために、機械でできることは機械に任せてしまおうという当初の目的も確かにあります。
ですが、それと同時に、「コンピューター」だからこそ得られる副次効果も非常に大きな恩恵をもたらしてくれます。
それが
「過ちを犯さない」
です。正確には、「命令されたことを忠実にかつ再帰的に実行する」です。そのため、人間が与える命令(プログラム)に誤りがなければ、コンピューターは常に、何度でも、繰り返し正確に、与えられた命令を実行してくれます。言い換えれば、処理(作業)品質が完璧なのです。
ですが、実際には「事故」が起きます。
「人(エンジニア)」が、「不良/欠陥」を取り除いておかなかったためです。なぜ、事故が起きるまでに「不良/欠陥(バグ)」を取り除いておけなかったのでしょう。
人間は「過ち(エラー)」を起こす。
エラーによって「欠陥(バグ)」を招く。
バグが動作することによって「故障」が引き起こされる。
さきほどの説明を引用すればわかると思いますが、この因果関係を読み解くと、つまり「コードの欠陥が実行されなければ「故障」は発見できない」と言うことがわかります。
だからこそ、コードの欠陥箇所を実行するための、テスト工程と言うものが常に用意されているわけです。
自動車でも同じですよね。
作ったらそのまま売る…なんてことはしません。製造業の場合は、製造ラインに乗せてしまえば同じモノが量産できるため、最初の製造品からサンプリング試験を行い、長距離走行試験や制動実験、衝突実験などを繰り返し、量産してもいいというお墨付きが出るまでテストします。
ソフトウェアでも、量産はコピペで済んでしまうため、基本的には初回に作ったときにまとめてテストしてしまいます。
もちろん、机上デバッグなどによってある程度の「発見」「解決」はできるのかもしれませんが、どうしても人の能力に依存するうえに、完全性が保証されるわけでもなく、机上デバッグだけで品質を保証するのはとても非効率です。
限られた時間の中で最大限の成果を出すのであれば、テストツールなどによる効率的な試験運用が最も品質を保証・管理してくれます。
しかし、上記の定義を見ればわかるように、まず何よりも第一に「テスト」工程において実施しなくてはならないものがあります。わかるでしょうか。「コードの欠陥が実行されなければ「故障」は発見できない」のです。
「実行されなければ」+「発見すらできない」
=「未実行のまま納品すれば」+「発見できずに送り出してしまう」
=「故障が無いことを証明しなければ」+「問題が発生する可能性が残る」
となるわけですから、すべてを実行するしかありません。
不良/欠陥を作りこんでしまうのは仕方ないとしても、それらを発見できないのは、
「不良/欠陥を実行していない」
「不良/欠陥を実行しているにもかかわらず、見逃している」
のどちらかを「人」がやらかしてしまっているからです。どこか、テストへの取り組みが疎かになっていると言うことです。
テストを完璧にする自信がないなら、モノ作りは任せられない
意外なことに現場では、カバレッジテストや組み合わせパターンの網羅テストを敬遠するエンジニアがいるのを見かけます。
一般的に、「モノづくり」が好きでこの業界に入ってきた人は、テストなどの検証フェイズを苦手としていたり、嫌っていたりする人が多いようです。
私も昔は眠くなるだけで、好きではありませんでした(実際、寝ていたこともあります…いやぁ、1回実行したら40分待たないと結果が出ないテストなんて、その間寝るしかなくって…)。
ですが、社会インフラに強く根差したシステムやソフトウェアを作る際には、最も重要で、最も神経を使わなくてはならないフェイズでもあります。
たとえば、交通機関の管制システムや、自動車のECUなどの場合は、そのまま多くの人命に影響を与えかねません。金融や行政のシステムをストップさせてしまったら確実にニュースの一面記事に載ります。
私自身、こうしたニュースや記事になるトラブルプロジェクトの支援や解決を何度もしてきたので、これらがどれくらい大事なのかよくわかっているつもりです。
ですから、各テスト工程を実施する際の観点にあわせて、それぞれのパターン網羅性をしっかりと検証することは怠りません。必ず何万、何百万と言うすべてのパターンを洗い出し、そこから観点が重複するテストケースをつぶしこんで件数を間引き、論理的に品質を保証できるパターン数分だけテスト実施するようにしています(デシジョンテーブルにすれば、多少手が釣ったり、腱鞘炎になったりはしますが、一番簡単なので)。
作った物には作った責任と言うものがあります。その責任を果たせないのであれば、「作る資格はない」と言われても仕方がないのではないでしょうか。
いただいたサポートは、全額本noteへの執筆…記載活動、およびそのための情報収集活動に使わせていただきます。