Skip to content

AAAとGWTの違い:同じに見えて実は違う話

はじめに

テストコードを書いていると、AAAやGWTという言葉に出会うことがあります。Arrange-Act-AssertとGiven-When-Then、どちらもテストを3つのステップで構造化するパターンです。「これって同じものを別の言い方してるだけじゃないの?」と思った方も多いのではないでしょうか。

実際に調べてみると、両者は確かに似ています。しかし、生まれた背景や使われる文脈が異なり、それぞれに適した場面があることがわかりました。この記事では、両パターンの違いをTDDとBDDの観点から整理し、どう使い分けるかをご紹介します。

AAAパターンとGWTパターンの基本構造

まずは両パターンの構造を確認しましょう。一見すると、名前が違うだけで同じことを言っているように見えます。

以下の図は、両パターンの対応関係を示しています。


flowchart LR
    subgraph AAA["AAAパターン"]
        A1[Arrange
準備] A2[Act
実行] A3[Assert
検証] end subgraph GWT["GWTパターン"] G1[Given
前提条件] G2[When
操作] G3[Then
期待結果] end A1 -.-> G1 A2 -.-> G2 A3 -.-> G3

AAAパターン(アレンジ・アクト・アサートと読みます)は、テストを「準備」「実行」「検証」の3段階に分けます。一方、GWTパターンは「前提条件」「操作」「期待結果」という構成です。対応関係を見ると、ほぼ同じに見えますよね。

AAAパターンの具体例

AAAパターンを使ったユニットテストの例を見てみましょう。


// AAAパターンの例
test('商品の合計金額を計算できる', () => {
  // Arrange(準備)
  const cart = new ShoppingCart();
  cart.addItem({ name: '本', price: 1500 });
  cart.addItem({ name: 'ペン', price: 200 });

  // Act(実行)
  const total = cart.calculateTotal();

  // Assert(検証)
  expect(total).toBe(1700);
});

このパターンでは、テストの各段階が明確に分離されています。何を準備して、何を実行して、何を検証するのかが一目でわかります。

GWTパターンの具体例

同じテストをGWTパターンで書くと以下のようになります。


// GWTパターンの例
test('カートに商品を追加したとき合計金額が計算される', () => {
  // Given(前提条件)
  const cart = new ShoppingCart();
  cart.addItem({ name: '本', price: 1500 });
  cart.addItem({ name: 'ペン', price: 200 });

  // When(操作)
  const total = cart.calculateTotal();

  // Then(期待結果)
  expect(total).toBe(1700);
});

コードの構造はほぼ同じです。しかし、テスト名やコメントの書き方に違いがあることに気づきましたでしょうか。

TDDとBDDという異なる背景

両パターンの違いを理解するには、それぞれが生まれた背景を知る必要があります。


flowchart TD
    subgraph TDD["TDD(テスト駆動開発)"]
        T1[開発者視点]
        T2[実装の正しさを検証]
        T3[AAAパターン]
    end

    subgraph BDD["BDD(振る舞い駆動開発)"]
        B1[ユーザー視点]
        B2[振る舞いを記述]
        B3[GWTパターン]
    end

    T1 --> T2 --> T3
    B1 --> B2 --> B3

AAAパターンの背景にあるTDD

AAAパターンは、TDD(Test-Driven Development、テスト駆動開発)の文脈で広く使われています。TDDは開発者がコードを書く前にテストを書く手法です。

TDDの焦点は「実装が正しく動くか」にあります。開発者が自分のコードをテストするために使うパターンなので、技術的な視点で書かれます。テストの対象は関数やメソッドといった実装の単位です。

GWTパターンの背景にあるBDD

GWTパターンは、BDD(Behavior-Driven Development、振る舞い駆動開発)から生まれました。BDDはTDDを発展させた手法で、Dan North氏が2006年に提唱しました。

BDDの焦点は「システムがどう振る舞うか」にあります。ユーザーやビジネス関係者も理解できる言葉で仕様を記述することを重視します。そのため、GWTパターンは自然言語に近い形式で書かれることが多いです。

BDDについてより詳しく知りたい方は、Dan North氏の原著記事が参考になります。BDDという概念が生まれた経緯や、なぜGiven-When-Then形式が採用されたのかを理解できます。

Introducing BDD – Dan North

両パターンの本質的な違い

構造は似ていても、両パターンには本質的な違いがあります。以下の観点から比較してみましょう。


flowchart TD
    subgraph AAA視点["AAAの視点"]
        A1[このメソッドに
この入力を与えると] A2[この出力が
返される] end subgraph GWT視点["GWTの視点"] G1[この状況で
ユーザーがこの操作をすると] G2[このような結果が
得られる] end A1 --> A2 G1 --> G2

視点の違い

AAAパターンは開発者視点です。「このメソッドにこの引数を渡すと、この値が返る」という技術的な観点でテストを書きます。

GWTパターンはユーザー視点です。「この状況でユーザーがこの操作をすると、こうなる」というシナリオベースの観点でテストを書きます。

テスト名の書き方の違い

この違いはテスト名に顕著に表れます。

AAAパターンのテスト名:

  • calculateTotal_withTwoItems_returnsSum
  • validateEmail_withInvalidFormat_returnsFalse

GWTパターンのテスト名:

  • カートに商品を追加したとき合計金額が表示される
  • 無効なメールアドレスを入力したときエラーメッセージが表示される

GWTパターンでは、非エンジニアが読んでも理解できる記述を目指します。

使われるツールの違い

AAAパターンは、JUnit、Jest、pytestなど一般的なテストフレームワークで使われます。

GWTパターンは、Cucumber、SpecFlow、Behaveなど、BDD専用のツールでよく使われます。これらのツールでは、Gherkin構文という自然言語に近い形式でテストシナリオを記述できます。


# Gherkin構文の例
Feature: ショッピングカート
  Scenario: 商品の合計金額を計算する
    Given カートに1500円の本が入っている
    And カートに200円のペンが入っている
    When 合計金額を計算する
    Then 合計金額は1700円である

使い分けの考え方

では、どちらのパターンを使えばよいのでしょうか。以下のような基準で考えると整理しやすいです。


flowchart TD
    Q1{テストの目的は?}
    Q1 -->|実装の検証| A[AAAパターン]
    Q1 -->|仕様の記述| Q2{関係者は?}
    Q2 -->|開発者のみ| B[どちらでもOK]
    Q2 -->|非エンジニアも含む| C[GWTパターン]

AAAパターンが適している場面

ユニットテストや技術的な検証が目的の場合、AAAパターンが適しています。開発者だけがテストコードを読み書きする環境では、シンプルなAAAパターンで十分です。

また、既存のテストフレームワークをそのまま使いたい場合も、AAAパターンが自然な選択になります。特別なツールを導入する必要がありません。

GWTパターンが適している場面

受け入れテストや仕様の文書化が目的の場合、GWTパターンが適しています。プロダクトマネージャーやビジネス側の関係者とテストケースを共有したい場合に効果的です。

また、テストを「生きた仕様書」として活用したい場合も、GWTパターンが向いています。自然言語に近い形式で書かれたテストは、仕様の理解を助けます。

両方を組み合わせる

実際のプロジェクトでは、両方を組み合わせることも珍しくありません。ユニットテストはAAAパターンで書き、E2Eテストや受け入れテストはGWTパターンで書く、という使い分けが一般的です。

重要なのは、チーム内で一貫したルールを決めておくことです。同じ種類のテストで両パターンが混在すると、コードの可読性が下がります。

終わりに

AAAとGWTは、一見すると同じパターンの別名に見えます。しかし、TDDとBDDという異なる背景から生まれており、視点や目的に違いがあることがわかりました。

どちらが優れているというものではありません。テストの目的や関係者に応じて、適切なパターンを選ぶことが大切です。まずは両方を試してみて、チームに合ったスタイルを見つけてみてください。

テストパターンについてさらに詳しく知りたい方は、以下のリソースも参考になります。

テスト駆動開発(Kent Beck著、和田卓人訳)

TDDの原典の日本語訳です。AAAパターンの背景にあるテスト駆動開発の考え方を体系的に学べます。

実践テスト駆動開発(Steve Freeman、Nat Pryce著、和智右桂・高木正弘訳)

モックを活用したテスト駆動開発の実践書です。テストの構造化やリファクタリング手法を具体例とともに学べます。

Cucumber公式ドキュメント – Gherkin Reference

GWTパターンで使われるGherkin構文の公式リファレンスです。Given-When-Thenの書き方を詳しく解説しています。

コメントを残す