バグやトラブルから考える「コロンブスの卵」

# この記事は何？
バグやトラブルの原因は、それが起きたあとから考えると「さも簡単」なことに思えるし
やもすれば「なんでこんなこともテストしてなかったの？」と批判の的になってしまう。
が、実際はバグやトラブルが「起きる前」に、そうした原因の種を潰すのはめちゃくちゃ難しいんだよってことを改めて認識しましょうね。というお話です。

## 簡単に批判していいものか？
ソフトウェアが社会に浸透し、あらゆる産業活動から趣味までソフトウェア抜きに語ることができない世の中になった。
その結果、ソフトウェアのバグやシステムのトラブルが与える影響はとても大きなものになっている。
かつて、とある金融機関でシステムトラブルが起きたとき、某朝の情報番組のコメンテータがこんな発言をしていた。
 ***「私ですらパソコンで家計簿をつけているが問題を起こしたことはない。」***

![news_wideshow_serious.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181045/a1cee257-f740-115b-ffe8-b7e8c8f7b3ed.png)

私はこの発言に強く憤りを覚えました。
個人がパソコンで家計簿をつけることと、金融機関の勘定系はシステムの構築難易度でいうと天と地ほどの差があるのだ。
確かにシステムトラブルは起きてほしくないし、起きないように努めるべきものである。
しかし、報道側が勝手に問題を矮小化し、過度な批判をしてしまえば、今後ソフトウェア開発においてMTBF(*1)を高くするための過度な投資が進んでしまう可能性がある。
すなわち、日本のソフトウェア開発生産性の低下を招きかねないのだ。

(*1) Mean Time Between Failure（平均故障間隔）

## バグはコロンブスの卵
<img width="300" alt="system_integration.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181045/971ff626-c222-8650-51cf-109c7bc56314.png">

そもそも世の中にあふれるソフトウェアのほとんどは、驚くほど複雑な構造をしている。
ソフトウェアの要件や仕様、アーキテクチャや基盤の構成・設定、開発組織、ヒト/モノ/カネなどのマネジメント要素…
非常に多くの要因が複雑に絡み合い、1つのバグを引き起こしている。
実際にトラブルが発生した際、そのソフトウェアの開発・運用をしている組織は全力でその解明にあたっている。
しかし、その分析も容易ではない。
ログやデータから事実関係の把握を行い、経験も知識も豊富なエンジニアが問題の切り分けを進め、多くの技術者が問題の特定のために解析や仮説の検討を集中して何時間も行う。
が、僕たちは報道を見ることで簡単にバグの原因を知ることができる。
原因の特定がそんなに難しいことだとは思いもしない。
だから報道を見たらこう考えてしまうのだ。
***なんでこの程度のことを事前にテストしていないの？***

<img width="200" alt="columbus_egg.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181045/084f1a64-d33a-5a46-ce81-59d10bbc160a.png">

これはまさに***コロンブスの卵***だ。
どんなに難しい問題も、1度衆目に晒されれば非常に簡単なものに見えてしまう。
しかし、それを最初に見つけるのはものすごく難しいことなのだ。

## 事前にテストするのは難しいこと
ましてや、バグが起きてもいない開発中の段階で、その原因を潰すことは輪をかけて難しい。
トラブルが発生してしまえば、事象そのものやログ、データがヒントとなってくれるので何とか原因が特定できる。
しかし、開発中にはそんなヒントはない。
タスクの期限が迫り、要件は曖昧だけどテストしたい仕様は山ほどある。予算もリソースも限界がある。
そんな中でも極力バグを起こさないようにテストをしているのだ。
[ISTQBテスト技術者資格制度 Foundation Level シラバス](https://jstqb.jp/syllabus.html)には「ソフトウェアテストの7原則」が示されている。
そのうちの1つに***全数テストは不可能***というものがある。
そう、考えうる全てのパターンをテストする。というのは不可能なのだ。
なんなら「考えうる全て」では足りない。
それどころか僕らは完全な要件や仕様を出すこともできないので、
「テストをするまで考えてもいなかったこと」もテストしなければいけないのだから、その難しさは例えるのが難しいほどである。

## じゃあどうすればいいのか？
とはいえ、ソフトウェアの運用をする人も、開発をする人もバグやトラブルを軽視しているわけではない。
やっぱりできるだけトラブルは起きてほしくないのだ。
だから私個人としては次のようなことに気をつけて開発をすべきだと考えている。

1. 全数テストが無理だからといって適当にテストするのではなく、リスク戦略や優先度を用いてテストを進める
1. 開発時には「起きてほしくないトラブル」や「まだ見ぬリスク」について考える機会をもつ(*2)
1. バグは絶対に残存しているという前提で開発や運用を行う(*3)

これも容易なことではない。
が、私達ができることはこの程度にすぎないのだ。
決して「バグはありません。」「全部テストしました。」などとぬかしてはならない。
***テストとはそもそも根本的に極めて難しいことである***と認識した上で、テストだけで全てを救おうとせず
クソ忙しい中でもビジネス目標とのトレードオフを調整しながら、あらゆる方策でもってリスクに備える心構えをすべきでしょう。

(*2) [前回の記事で書いたナイトメアヘッドラインゲーム](https://qiita.com/kumaichi/items/575fd9eb3dd3bd593c51)につながる
(*3) [例えばリスクへの対応方針](https://qiita.com/kumaichi/items/575fd9eb3dd3bd593c51#%E3%83%AA%E3%82%B9%E3%82%AF%E3%82%92%E8%80%83%E3%81%88%E3%81%9F%E3%81%82%E3%81%A8%E3%81%AF)を考えておく必要がある

# バグやトラブルに遭遇したときに落ち着いて考えてほしいこと
ひとたびバグが起きればマスコミを中心に非難が殺到する。SNSでも批判が溢れ、すぐに炎上する。
中には口汚い言葉で罵る輩も出てくる。
そうした非難をするほとんどの人はおそらくソフトウェア開発に従事した経験がない。
だから簡単に非難してしまう。
ソフトウェア開発に従事したことがある人でも、自分の経験したドメインと異なる領域については注意したい。
開発しているものが違えば、その開発が抱えるリスクや難易度、複雑さは全く異なるものなのだ。
スマホゲームと金融機関の勘定系システム、不動産検索サイトと救急医療機器の組み込みシステム…
こうしたものが同一に扱われていいわけがない。
マンションと一戸建て、迎賓館のディナーと家の晩ごはん、それぞれがそれぞれに作る難しさや抱えるリスクは違うのだ。
いずれかの経験がないのであれば、自分の経験だけを物差しにして安易に批判し、語るべきではない。
冷静に情報を見て、口汚く罵る前にまずは落ち着いて考えてみることを推奨したい。
（これは、ソフトウェアに限った話ではない。）

今後ソフトウェアに関する教育が国内で進んでいくことで
少なくともソフトウェアに関することで、こうした「コロンブスのたまご」に騙されず、落ち着いて議論ができるようになっていってほしいと想います。

私自身も[なにか貢献できないか](https://www.kyoiku.metro.tokyo.lg.jp/static/kyoinsenko/menkyo/m_tokubetsu.html)と考えているところです。

![businessman2_kangaechu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181045/61898965-359d-a304-5719-22dbdd01f070.png)