テスト駆動開発(TDD)は、完成したコードに後からテストを足すだけの方法ではありません。期待する動きを先に一つ書き、短いフィードバックを得ながら設計します。
練習する関数
税込価格を返す関数を作ります。ここではNode.js 22の組み込みテスト機能を使います。
Red:まず失敗させる
// price.test.js
import test from "node:test";
import assert from "node:assert/strict";
import { calculateTaxIncluded } from "./price.js";
test("1000円に10%の税を加える", () => {
assert.equal(calculateTaxIncluded(1000, 0.1), 1100);
});
まだ price.js がないため、テストは失敗します。失敗理由が期待どおりであることを確認します。
Green:最小の実装で通す
// price.js
export function calculateTaxIncluded(price, taxRate) {
return price * (1 + taxRate);
}
node --test price.test.js
ここでは、将来必要そうな通貨変換や割引機能を先に作りません。
Refactor:動きを変えずに整える
小数の扱いを明確にする要件を追加します。
test("小数になった金額は切り捨てる", () => {
assert.equal(calculateTaxIncluded(999, 0.1), 1098);
});
export function calculateTaxIncluded(price, taxRate) {
const total = price * (1 + taxRate);
return Math.floor(total);
}
テストがあるため、既存の動きを壊していないかすぐ確認できます。
小さく進める理由
一度に多くのテストを書くと、どの前提が間違ったか分かりにくくなります。
- 一つの期待を書く
- 期待した理由で失敗する
- 最小のコードで通す
- 名前や重複を整える
- 次の期待へ進む
この短い周期がTDDの中心です。
TDDが向かない時
見た目を探索している初期UIや、使い捨ての検証コードでは、先に動かして学ぶ方が早い場合があります。すべてをTDDにするのではなく、入力と出力が明確なロジックから試します。