AAAパターンで実現するクリーンなテストコード
公開日2024.12.03
あなたは次のようなテストコードを見たことはありませんか?
test('商品追加のテスト', () => {
const cart = new ShoppingCart();
expect(cart.getTotal()).toBe(0);
cart.addItem('apple', 100);
expect(cart.getTotal()).toBe(100);
cart.addItem('banana', 150);
expect(cart.getTotal()).toBe(250);
});
一見問題なさそうに見えるこのテストコード。しかし、このような書き方には実は大きな問題が潜んでいます。今回は、テストコードを整理するための重要な考え方「AAAパターン」について解説します。
AAAパターンとは?
AAAパターンは、テストコードを以下の3つのフェーズに分けて構造化する手法です。
- Arrange(準備):テストに必要な前提条件を整える
- Act(実行):テスト対象の機能を実行する
- Assert(確認):期待する結果が得られたかを検証する
この3つのフェーズを明確に分けることで、テストの意図がクリアになり、保守性が大幅に向上します。
悪い例と良い例で学ぶAAAパターン
悪い例:フェーズが混在したテストコード
test('商品追加時の合計金額テスト', () => {
const cart = new ShoppingCart();
expect(cart.getTotal()).toBe(0); // 準備と確認が混在
cart.addItem('apple', 100); // 実行
expect(cart.getTotal()).toBe(100); // 確認
cart.addItem('banana', 150); // また実行
expect(cart.getTotal()).toBe(250); // さらに確認
});
このコードの問題点
- 各フェーズの境界が不明確
- 複数の動作を一度にテストしている
- テストが失敗した際の原因特定が困難
良い例:AAAパターンを適用したテストコード
test('商品追加時の合計金額が正しく計算されること', () => {
// Arrange(準備)
const cart = new ShoppingCart();
const testItems = [
{ item: 'apple', price: 100 },
{ item: 'banana', price: 150 }
];
const expectedTotal = 250;
// Act(実行)
testItems.forEach(({ item, price }) => {
cart.addItem(item, price);
});
const actualTotal = cart.getTotal();
// Assert(確認)
expect(actualTotal).toBe(expectedTotal);
});
改善された点
- テストの各フェーズが明確に分離されている
- テストの意図が理解しやすい
- 期待値と実際の値の比較が1か所にまとまっている
- デバッグが容易
AAAパターンを実践するためのTips
1. コメントでフェーズを区切る
// Arrange
// Act
// Assert
2. 空行でフェーズを視覚的に分ける
// Arrange
const service = new Service();
const input = 'test';
// Act
const result = service.process(input);
// Assert
expect(result).toBe('TEST');
3. 各フェーズの役割を意識する
- Arrange:テストに必要なオブジェクトの生成、データの準備
- Act:テスト対象の機能を1回だけ実行
- Assert:期待する結果との比較を行う
AAAパターン採用のメリット
- 可読性の向上
- テストの流れが一目で分かる
- コードレビューが効率化される
- 保守性の向上
- テストの修正が容易になる
- 新しいテストケースの追加がスムーズ
- デバッグの効率化
- テスト失敗時の原因特定が容易
- どのフェーズで問題が発生したかが明確
まとめ
AAAパターンは、テストコードを整理するための強力なツールです。このパターンを意識することで
- テストの意図が明確になる
- コードの保守性が向上する
- チーム内でのコード理解が促進される
特に大規模なプロジェクトや長期的なメンテナンスが必要なコードベースでは、AAAパターンが推奨されます(`・ω・´)
みなさんも、次回テストコードを書くときは、AAAパターンを意識してみてはいかがでしょうか?