「バグ」と呼ぶのをやめて、名前をつけてあげよう
パグにもそれぞれ名前がある(この写真は Unsplash で見つけたものだから、おれは彼らの名前を知らない)
ある日の午後、オフィスでサポートエンジニアとQAが会話していた。
サポートエンジニアは言った。「すべてのバグを直すことなんて不可能だ」。
QAはこう返した。「そんなことはない。バグとはただの考慮漏れだ。バグが市場に出るということは、テストするときになにかのパターンを考慮していなかった。ただそれだけだ。」
「その考えは素朴すぎる。例えば我々のSDKがユーザーの使っている別のサードパーティーのライブラリと相性が悪いことだってあるだろう。こういう組み合わせは無限にある。すべてを考慮することは出来ない。」
QAは更にこう返した。「それは 互換性 という別の問題だ。おれが言っているのは 機能性 に関するものだ。」
サポートエンジニアは尚も言う。「それにしたって、すべてのパターンをテストすることは出来ない。お前はテスターのくせに 全数テストは不可能 だという事実すら知らないのか?」
「わかった。同値分割や境界値分析を用いて導いた代表値で見つからないバグもあるということだな。例えば、ランダムな数 42 が突然問題を引き起こすことがある。」
「そうだ。」
QAはこう続けた。「とどのつまり、おれたちはそのランダムな数 42 が使われる ユースケース を想定していなかったということになるんだろう?おれたちの テスト分析 が完璧じゃなかったというだけの話じゃないか。」
「じゃあ、ハードウェアの故障の問題はどうなんだ?おれは先週もサーバールームにこもりっきりだった。故障したハードディスクを特定するのに数日を費やし、交換した。これも事前にテストできるのか?」
「問題はそこじゃない。おまえはハードウェアの故障の問題と互換性の問題、それに機能性の問題を バグ という一つの単語で表そうとしていないか?」
「何か問題があるのか?ユーザーに対して悪影響を及ぼすものはすべてバグだろ?」
「おまえがそう呼びたいならそれでも良いよ。でも、 異なる原因を持つ異なる事象を一つの言葉で表す のは明らかにアンチパターンだ。おれは機能面での不具合を、ユースケースレベルですべてテストして、すべてのバグを見つけて直すことは現実的だと思っている。」
「そうか、わかった。バグにも色々な種類があるんだな。ところで、先週おれがサーバールームにこもりっきりになった件はどうしたら事前にテストできるんだ?もうアラート対応にはほとほと疲れたんだ。」
「お疲れさま。問題は、ハードウェアの故障によって引き起こされる問題を事前に予測できなかったことだろ?こういうのはいくつかやりかたがあるんだ。例えば、カオスエンジニアリングというのがあってだな……」
この対話はフィクションだが、ありふれたものだと思う。この対話によく現れているように、おれたちはあまりに多くの問題を バグ という一つの言葉で片付けている。互換性の問題、サードパーティーライブラリのバグ、ハードウェアの故障、CPUやメモリ利用率のスパイク、レースコンディション(競合)、それにごくありふれた(ありふれてほしくないが)機能面での瑕疵だ。
ユーザーはすべてを バグ という呼び名で呼ぶ。これはしょうがない話だ。ユーザーにとって、ソフトウェアプロダクトは、それの土台になるハードウェアと共に、ブラックボックス、中身の見えない箱に過ぎない。その中で何が起きていようとも - 例えば、 バグ という言葉の起源とされているように、本物の虫がハードウェアに入ったとしても - ユーザーにとっては バグ としか言いようがない。不具合や欠陥など、他の別の言葉に置き換えても、結局中身が見えないという点では同じことだ。
一方で、開発者やQA、その他ソフトウェア・プロダクトに 内部的に関わる 人たちにとっては、十把一絡げにすべてをバグを呼んでしまうのはアンチパターンだ。先の対話に出てきたように、異なる原因を持つ異なる事象を一つの言葉で表すのは一般的に言ってあまり良いことではない。それぞれの問題に適切に対処するためには、問題に正しい名前を付けて、それぞれに対して適切な取り組み方を設定する必要がある。
バグを分類する
先に書いたように、ユーザー目線ではなおもって バグ と呼ぶことが許される - というか、それ以外の視点では基本的に許されない。 バグ、不具合、欠陥、何でも良いが、そういう呼び方が許されるのはそのプロダクトの利用者だけである。
じゃあ、このバグになんて名前をつけようか。もちろん、 CPU負荷が高まった時に、アプリケーションがクラッシュする なんて呼び方でも良いのだけど、もっと抽象化した名前が良い。
BTS (Bug Tracking System) や、JIRAなどのチケット管理システムでもいいのだが、あなたが バグ と分類したチケットに Bug Resolution という項目を足して、次のような分類をするのはどうだろうか。
- ユースケースの考慮漏れ
- ユーザストーリーの考慮漏れ
- ユーザー環境との互換性
- サードパーティーのバグ
- コンポーネントの故障
- レースコンディション
- 再現が困難な問題
分類する際には、原因に着目するのが良い。結果は要するにユーザーに対する不利益なので、分かりきっているからだ。
分類ごとに適切なアプローチを選択する
冒頭の対話を読み返して見て欲しい。サポートエンジニアは自身の経験から「すべてのバグを直すなんて不可能だ」と言っている。現場で見つかったエッジケース中のエッジケースに日々向き合っている彼の立場からすれば、そんなものをテストで全部見つけるなんて不可能だと断じるにいささかの迷いもないだろう。
一方で、QAは「すべてのバグを直したい」とまでは言っていないものの、それが不可能だとも言っていない。なぜなら、彼の職責は事前にできる限りのバグを見つけることだからだ。「すべてのバグを見つけて直すのが不可能だというのなら、自分は何のためにここにいるんだ?」、そんなプロ意識が彼の中にはある。
だが、対話の中でも明らかになっているように、彼らは異なる問題を バグ という一つの言葉で語ろうとしていた。だから会話に齟齬があった。しかし、会話の中で彼らは自分たちが扱っている バグ が分類可能であることに気づき、それぞれに対して適切な対応を取ることを選択した。
例えば、彼らは今後こんなガイドラインを作ることが考えられるだろう。
- ユースケースとユーザーストーリーに対応するテストは、自動テストによるカバレッジ100%を目指す。
- 互換性に関する問題については、それが再現可能な問題である限りは、自動テストによってカバーすることを目指す。
- 自社が使っているサードパーティーライブラリのバグについては、出来る限り自社のユニットテストで動作を保証し、継続的なアップデートを行う。
- ハードウェアやシステムコンポーネントの故障については、カオスエンジニアリングの手法を取り入れ、継続的に故障に対する実験を行う。
- レースコンディション(競合)については、設計段階で形式仕様記述による発見を目指す。
- 再現が困難だが継続して報告される問題については、既知の問題としてユーザーと共有する。
バグの分類は品質向上の第一歩
一口に バグ といっても、その原因には様々なものが考えられる。原因が違えば取りうるアプローチが異なるのは当たり前の話だ。逆に、やみくもにバグだバグだ、バグを直せとやっていても効率が悪い。直さないといけないのはバグそのものではないかもしれないからだ。ひとつ上のセクションの “ハードウェアやシステムコンポーネントの故障” についての対応を見てほしい。故障を直すとは一言も書いていない。故障しても問題ないかどうか実験を繰り返し、システムのレジリエンスを高めるのがこの種の問題に対する最適解だ。
問題をふるいにかけて、分類して、それぞれに名前をつけて、一つ一つ解決していこう。筆者の好きなことわざを最後に紹介しよう - 「テストだけで品質は向上しない」。問題に対する解決策を見つけ、繰り返し改善していくことでしか品質は高まらないのだ。バグを見つけ、分類し、直そう。それが品質向上に向けた、バグに対する取り組み方だ。
コメントを送る
コメントはブログオーナーのみ閲覧できます