デバッグ(その1)
テストチーフ「お、b! あれの受け入れテストを始めたんだけど…」
b君「なんかあった?」
テストチーフ「あったよ~、ふふふ」
b君「なに?」(なにその嬉しそうな顔、オレよっぽどマヌケなバグをやっちゃった!?)
テストチーフ「18以降、そのまま出てくるんだよ~♪」
b君「…え!? ……あ、ありがとう…」(なんてこった! マヌケ過ぎだ!)
最後に追加するはずのテストケースを、電話か何か割り込みが入って、忘れたままリリースしてしまったようです。b君、バグを見つけてくれたお礼はかろうじて言えたものの、そうとう落ち込んでいるようですね。
バグの原因になっている箇所を見つけ出すところまでは、従来と変わりません。もっとも、このb君の例のように、書いたテストを覚えているときに見つかったバグは、即座にその原因に思い至ることも多いものです。製品コードで問題のある場所が特定できたら、次は、そこをテストしているテストケースを探しますが、この例のようにテストケースが漏れている場合もよくあります。繰り返しますが、バグはテストケースが抜けていたか誤っていたために発生したのです。
デバッグを行うには、まず不具合を再現します。ここでは、テストケースの抜けが原因だと思われるので、再現するためのテストケースを追加します。
[TestCase(18, "Fizz")]
テストケースを追加したら、予想通りのREDになることを必ず確認します。
CsTdd04.FizzBuzzTest.FizzBuzzerTest.SayTest(18,"Fizz"): Expected string length 4 but was 2. Strings differ at index 0. Expected: "Fizz" But was: "18" -----------^
報告されたバグを再現するテストケースができました。これを含めてオールGREENにできれば、バグフィックスは完了のはずです。直すには、switch
文で分岐に使う値を引数そのものではなく、15で割った余りにすればよいですね。では、製品コードを修正します。
public string Say(int n) { if (n <= 0) throw new System.ArgumentOutOfRangeException(); switch (n % 15) { // ← 修正 case 3: case 6: // 中略 default: return n.ToString(); } }
これでオールGREEN …おっと、別のテストがREDになりました!
CsTdd04.FizzBuzzTest.FizzBuzzerTest.SayTest(15,"Fizz Buzz"): Expected string length 9 but was 2. Strings differ at index 0. Expected: "Fizz Buzz" But was: "15" -----------^
15で割った余りで分岐させるように変えたので、case 15:
のところは通らなくなってしまったのですね。ここはcase 0:
でなくてはいけません。再び製品コードを修正します。
public string Say(int n) { // 略 switch (n % 15) { // 略 case 0: // ←15を0に修正 return "Fizz Buzz"; default: return n.ToString(); } }
これでオールGREENになりました。デバッグ完了です。
なお、ここで追加したテストケースと同じ剰余になる3の場合のテストケースは不要になります。