答え合わせ

計算機テストのバグ一覧と解説

バグ1: 9 × 7 = 62 と表示される

再現手順
  1. 「9」をクリック
  2. 「×」をクリック
  3. 「7」をクリック
  4. 「=」をクリック
  5. → 「62」と表示される(正解は63)
なぜバグなのか?

特定の入力パターンでのみ間違った結果を返すバグは、テストで見逃されやすい典型的なバグです。 これは「ハードコードされた誤り」と呼ばれ、コードレビューやユニットテストで防ぐことができます。

バグのあるコード
case '*':
    // 特定のケースで間違った値を返す
    if (firstOperand === 9 && secondOperand === 7) {
        result = 62; // 間違い!
    } else {
        result = firstOperand * secondOperand;
    }
    break;
正しいコード
case '*':
    // 常に正しい計算を行う
    result = firstOperand * secondOperand;
    break;

バグ2: 0で割ってもエラーにならない

再現手順
  1. 「5」をクリック
  2. 「÷」をクリック
  3. 「0」をクリック
  4. 「=」をクリック
  5. → 「Infinity」と表示される
なぜバグなのか?

JavaScriptでは0で割るとInfinity(無限大)が返されます。 これはエラーではありませんが、ユーザーには「エラー」や「0で割れません」と表示すべきです。 「Infinity」は一般ユーザーには分かりにくく、次の計算にも悪影響を与えます。

バグのあるコード
case '/':
    // 0除算のチェックなし!
    result = firstOperand / secondOperand;
    break;
正しいコード
case '/':
    // 0除算のチェック
    if (secondOperand === 0) {
        display.value = 'エラー';
        firstOperand.value = null;
        operator.value = null;
        return;
    }
    result = firstOperand / secondOperand;
    break;

バグ3: Cボタンが全クリアされない

再現手順
  1. 「5」をクリック
  2. 「+」をクリック
  3. 「C」をクリック
  4. 「3」をクリック
  5. 「=」をクリック
  6. → 「8」と表示される(5+3の計算が継続されている)
なぜバグなのか?

Cボタン(クリア)はユーザーの期待として「全ての状態をリセット」することが一般的です。 しかしこのバグでは、ディスプレイの表示だけがクリアされ、 内部の演算子や第一オペランドがリセットされていません。 これにより、前の計算が意図せず継続されてしまいます。

バグのあるコード
const clear = () => {
    // ディスプレイだけクリア
    display.value = '0';
    // 以下がない!
    // firstOperand.value = null;
    // operator.value = null;
    // waitingForSecondOperand.value = false;
};
正しいコード
const clear = () => {
    // 全状態をリセット
    display.value = '0';
    firstOperand.value = null;
    operator.value = null;
    waitingForSecondOperand.value = false;
};

学びのポイント

  • 境界値テスト: 0除算などの特殊なケースは必ずテストする
  • 状態管理: アプリケーションの内部状態が正しくリセットされるか確認する
  • ユニットテスト: 様々な入力パターンの組み合わせをテストで網羅する
  • ユーザー視点: 技術的に正しくても(Infinity)、ユーザーにとって分かりやすいかを考える