バグの報告の仕方、というのはたぶん多くの人は新人研修で習う類の事だし、習わなかった人も世の中には「こう書け」という記事はたくさんあるのでググって読めば十分にも思う。 自分はそれらの記事を読んでないがたぶん十分良く書けていると思うし、別段何かを追加する必要も無いとは思っている。

ただ、バグの報告の仕方は割と簡単であるがゆえに、本になるほど難しくは無いから、「プログラマが読むべき書籍XX」みたいな記事などにも学ぶべき事としては出てこないし、 新人教育みたいなのがあまりちゃんとしてない所で育つと学ぶ機会が無く、「学ぶ必要がある事」という認識を持っていないというケースも結構見かける。

という事でたまにはバグの報告の仕方は学ぶべき事なんですよ、という事を発信しておく方がいいかな、と思い、 バグの再現率について何か書いてみるかな、と思ったのがこのポスト。

再現率の書き方

100%再現するバグ以外のバグは、基本的には再現率を書く。これは必須である。

そんな事言っても再現率って確率を書けって事?そんなの調べるの大変じゃん、となるかもしれないが、そうでは無い。 再現率は普通、何回試して何回再現したのかを書く。

例えば5回試して2回再現したら 2/5と書く。

これは確率40%では無いかもしれないじゃないか、というと、もちろんそう。 でもこの2/5を再現率と呼ぶ。 実際この2/5は、この時点で分かっている再現率に関する最良の推測である。

なお、40%と報告してはいけない。2/5と書こう。

再現率はコストをかけずに報告出来る

なぜ再現率を必ず書かないといけないのか、というと、これを知るのには追加のコストが必要無いからだ。 100%再現しないバグについて再現手順を調べたなら、必ず複数回試しているはずだ。 それを数えておきさえすれば、そのあと再現率を調べるために追加の作業は必要無い。 「バグの再現手順を調べる時には試行回数をメモしておく」という事さえ厳守しておけば、 追加で必要な作業が無いのだ。

この追加の作業が必要無い、というのはすごく重要だ。 なぜならバグの調査はコストが掛かるからだ。 どこまで報告側がコストを掛けて調査するべきかは状況とその人の責任次第だ。 人のコードからバグが出た、という時に、調査をすべきは発見した人では無くそのコードを書いた人である場合も当然ある。 だからやっておくと望ましい調査をすべて見つけた人がやるべき、という事は無い。

だが再現率は追加の調査を必要とせず書く事が出来る情報なので、100%再現するバグで無ければ「いつも」書くべきである。 そのためには再現手順を確認する時には必ず回数を「数える」というのを厳守する必要がある。 これが「教育」と呼ぶ内容の一つとなる。

一方で、何回試すべきか、というのは置かれている立場による。 当然たくさん試した方が良い訳だが、これは「必ずたくさん試すべき」とは言えない。 それには追加のコストが掛かるからだ。そのコストを払うのが誰であるべきかはシチュエーションによる。 だから試す回数が少ない事は場合によっては良くないし、場合によっては正しい。

だが再現率を書かないのは「いつも」間違っている。

再現率を書いてない駄目なケースを考える

再現率を必ず書くべき、というのは当たり前に聞こえるかもしれないが、ちゃんと教育されていないと意外と出来ない。 特に数えておく、というのは、あとからは出来ないので、最初に再現率を必ず書かなくてはいけない、と思っていないと出来ない。

その辺を実感するために、もう少し具体的な例を考えてみよう。

何かたまに再現するバグがある。原因はよく分からないし再現手順もよく分からない。 うーん、わからん、という状態から始まるのが良くある再現率の低いバグだ。

で、何度か遭遇すると「こういう感じの事をやっていると再現するかもしれない、どれが原因かはよく分からないけど」みたいな事に気づく事がある。 で、試してみると再現しない。あれ〜おかしいなぁ?とか思う。 これを繰り返していてだんだんとヒントを集めていく感じになる。

そしてある時、再現手順にたどり着いた気がする。再現手順を行ってもだいたい再現しないが、何度もやってると5分くらいで再現した! これで再現するんじゃないか?ともう一回再現手順をやると今度は15分くらいやってやっと再現した。 これは再現手順見つけたんじゃないか?とそのあと30分くらいやったら、全く再現しなかった。 あれぇ?これが再現手順じゃないのかなぁ?でも何回かは再現したんだよな。 とりあえずこれを現時点で分かっている再現手順として報告しよう。

こういう時に、「すぐに再現する事もありますが、全然再現しない事もあります」みたいな報告はしてはいけない、 といのが今回のポストの主旨だ。

再現するかどうか分からない時に、ちゃんとカウントしておく。5分試した時には何回試したのか。15分試した時には何回試したのか。30分試した時には何回試したのか。 そして何回試して何回再現したのかを書く。

この情報は、「すぐに再現する事もありますが、全然再現しない事もあります」よりも遥かに役に立つ。 しかもカウントさえしておけば追加でそれ以上試す必要はない。 ただでさえ30分試すのは大変だったのだ。それ以上試すなんて本業でも無くたまたま見つけた他人のバグにそこまで時間なんて掛けられないかもしれない。 ただ、カウントした数字を書くのは追加の試行はいらない。そしてカウントはほとんど追加のコストはかからない。

この追加のコストを掛けずに書く事が出来るから「いつも」書くべき、と言える項目となる。

実際には違う原因で、同じ回数を試しても全く再現しないかもしれない。 けれど、何回くらい試して何回くらい再現したのかの情報があれば、担当者は報告者に分からない多くの事を予想出来る。

こうしたバグは本当に何も分かって無い状態で報告する事がほとんどだ。 そもそもこの再現手順があっているかもよく分かっていない。 最後に30分試しても再現しないのは、そのあと何時間試しても再現しないかもしれない。 それを試すにはすごくたくさんの時間試してみないと分からないかもしれない。

こうした曖昧さというものについての情報を伝えるのに、とても簡単にできて有効なのが「数えてその回数を伝える」という事だ。 もちろんこれだけでは伝わらない事もあるし、 間違った思い込みを相手に与えてしまう事もある。 けれど、それよりもずっと多くの場合に役に立つ情報となる。

だから曖昧性からその数字にどのくらい正しさがあるのか自信が無くても、この情報は必ず書いた方がいい。 数えるだけで書けるから。 それは追加で1時間くらい試して本当にこの手順で再現するのかを試すのとは違う。 追加でそれ以上何かをする必要はない。 試した時点で得られている情報を書けば良い。

追加の情報は、書きたければ書けば良い

最初に5分で再現したが、最後は30分試しても再現しなかった、 というような情報は、重要かもしれない。

均等に試した回数分同じように再現するものではなく、何か他の要因があるかもしれない、という気もする。 担当者が同じ手順を同じ回数試しても再現しないかもしれない、という気もする。

そうした情報は書きたければ書けば良いと思う。それは役に立つかもしれない。 ただ、それは再現率を書かない理由にはならない。

しかも、このばらつきもどれだけ本質かはこの程度の試行回数ではよく分からない。 本当にたまたま最初に数回再現してそのあと再現しなかっただけで、 何か他の要因とかじゃなくて再現率が低いばらつきの可能性も十分にある。 そしてそのどちらかは現時点では分かっていない。

実際、中心極限定理などを考えれば、統計的にはそれらの数字には感覚的に感じる以上に意味がある事も多い。 そういった理屈はおいといても、やはり追加でそれ以上試行時間を重ねなくても書く事が出来る情報なのだから、 書いておく方がいい。

なぜ書きたくないのか

あんまりにも再現の仕方に規則性がないと、この数字を書くのに結構な抵抗を受けるのも分からないでもない。 間違った事は言いたくないので、低い再現率のものについてはこうした事を書きたくないという気もしてしまう。

再現手順が曖昧でなかなか再現せず、再現する時としない時の規則性も全然分からない。 こういう時に「再現率も書きましょう」とか言われても、「再現率なんてわかんねーよっ!そんな簡単なバグじゃないしっ!っていうかこれ以上もう試したくないよっ!」と思うかもしれない。

これは実際にそういうバグを相手にしてみないと分からない感情だ。 バグの報告に「再現率も書きましょう」とか言われても、 現実はそんなに単純じゃない、と思うかもしれない。

だが、試した回数や時間をカウントして再現した回数を書く、というのは、 そういったさっぱりなんだか分からないようなバグに対しても行える。

そして、そういうバグこそまさにこうした情報がすごく重要なのだ。 すごく規則性が無く再現手順があっているかどうかもよく分からず、 しかも再現させるのに凄い時間が掛かり、再現するかどうかもよく分からないようなバグ。

ソフトウェア開発では、そうした曖昧性さをコミュニケートする必要があり、 これはなかなかの難しさがある。

けれどこのカウントして回数を報告する、というのは、 この曖昧さをすごくうまく切り取って伝える単純だが強力な手法だ。 だからこそ最初にカウントする事の大切さをしっかりと学んで、 こうした強敵に直面した時にそのスキルを使えるようにしておく必要がある。

まとめ:再現率を書こう

という事で、何回試して何回再現したのか、は、必ず書こう。 そのためには再現方法を確認するために何回か試した時は、何回試したかを必ずカウントするようにしよう。 時間で再現するなら時間を測ろう。

その値はばらつきがあって正しくないように思えるかもしれないが、それでもないよりもずっと良い。

そしてこれは測るのに追加のコストがほとんど掛からないので、 書かない正当性はほぼすべてのケースで無い。

だから再現率を書こう。