Python & BehaveによるBDD入門:コードとビジネスの「共通言語」を作る

Python tutorial - IT technology blog
Python tutorial - IT technology blog

クイックスタート:5分で最初のBDDシナリオを実行する

退屈な理論を分析する代わりに、まずは手を動かしてみましょう。BDD(振る舞い駆動開発)とは、本質的にユーザーがソフトウェアを操作するストーリーを語ることです。Pythonエコシステムにおいて、それを実現する最強の味方がBehaveです。

ステップ1:ライブラリのインストール

pip install behave

ステップ2:標準的なディレクトリ構造の作成

Behaveはファイル構造に厳格です。エンジンがシナリオを自動的に認識できるように、以下のように正しく配置する必要があります:

my_project/
├── features/
│   ├── steps/
│   │   └── calculator_steps.py
│   └── calculator.feature

ステップ3:シナリオの作成(.featureファイル)

calculator.featureファイルを開きます。ここでは、上司や顧客も理解できるGherkin言語(英語または日本語)を使用します:

Feature: 基本的な計算機

  Scenario: 2つの整数の足し算
    Given 数値5がある
    And 数値10がある
    When 足し算を実行する
    Then 結果は15になるはず

ステップ4:ロジックの実装(.pyファイル)

steps/calculator_steps.pyファイルで、上記の各行に対応するPythonコードを定義します:

from behave import given, when, then

@given('数値{num:d}がある')
def step_given_number(context, num):
    if not hasattr(context, 'numbers'):
        context.numbers = []
    context.numbers.append(num)

@when('足し算を実行する')
def step_when_add(context):
    context.result = sum(context.numbers)

@then('結果は{expected:d}になるはず')
def step_then_check(context, expected):
    assert context.result == expected, f"計算ミスです!結果は {context.result} でした"

ステップ5:実行して確認する

ターミナルでbehaveコマンドを入力します。画面に緑色の文字で「1 scenario passed」と表示されれば、プロフェッショナルな自動テストの世界への第一歩を踏み出したことになります。

なぜAgileチームはBDDに熱狂するのか?

完璧なユニットテストを書いたのに、顧客に見せたら首をかしげられたことはありませんか?それは、従来のテストコードがあまりにも無機質だからです。BDDは、Gherkinを情報の架け橋として使うことで、このギャップを埋めるために誕生しました。

  • Given(前提条件):サンプルデータの設定やブラウザの初期化など, 初期状態をセットアップします。
  • When(操作):クリックやAPI呼び出しなど、ユーザーの操作を記述します。
  • Then(期待される結果):出力が期待通りかどうかを検証します。

Behaveはインテリジェントなマッピングツールの役割を果たします。Gherkinの各行をスキャンし、対応する@given@when@then関数を探し出します。特に、contextオブジェクトは「魔法のバッグ」のように機能し、同じシナリオ内のステップ間でデータを失うことなくスムーズに受け渡すことができます。

高度なテクニック:テストケースを無駄に肥大化させない

100セットのデータをテストする必要がある場合、シナリオを100回コピペしますか?その必要はありません。Scenario Outlineを使えば、ループ処理のような仕組みでコードを書く手間を80%削減できます。

Scenario Outline: 複数の計算をテストする
  Given 数値<so_1>がある
  And 数値<so_2>がある
  When 足し算を実行する
  Then 結果は<ket_qua>になるはず

  Examples: テストデータ
    | so_1 | so_2 | ket_qua |
    | 1    | 2    | 3       |
    | 10   | 20   | 30      |
    | 99   | 1    | 100     |

BehaveはExamplesテーブルに基づいてシナリオを自動的に再実行します。この方法は、featureファイルを煩雑にすることなく境界値(edge cases)を処理するのに非常に効果的です。

Hooksによるライフサイクル管理

Webの自動化を行う際、ブラウザを何度も開閉するのはリソースの無駄です。environment.pyファイルを活用して、実行プロセスを制御しましょう:

  • before_all: 共通設定を一度だけ行います。
  • before_scenario: 各シナリオのためにクリーンな環境を準備します。
  • after_scenario: ゴミ清掃、ブラウザの終了、テスト失敗時のスクリーンショット撮影などを行います。

実践導入における「血の滲むような」教訓

BDDシナリオを書くのは簡単ですが、プロジェクトの年月が経ってもそれを維持するのは別の話です。以下に、私が導き出したいくつかのヒントを紹介します。

1. 正規表現とサポートツールの力

Behaveでは、正規表現(Regex)を使用してパラメータを柔軟に取得できます。複雑なパターンに遭遇した場合は、誤判定を防ぐために慎重にチェックする必要があります。私はよく、ブラウザ上でパターンを素早く確認するためにToolcraftの正規表現テスターを使用しています。これはGherkinシナリオのデバッグ時間を大幅に短縮してくれます。

2. 「Less is More(少ないほど豊か)」の原則

Andを使いすぎないようにしましょう。1つのシナリオが20行にもなる場合、それは技術的な詳細に踏み込みすぎている兆候です。それらをグループ化しましょう。各クリックを説明する代わりに、「ユーザーがVisaカードで支払いを完了する」と記述します。これにより、シナリオがすっきりし、ビジネス上の価値が高まります。

3. 分割統治(モジュール化)

プロジェクトが大きくなるにつれ、steps.pyファイルは混沌としてきます。auth_steps.pypayment_steps.pyのように、モジュールごとに細かく分割しましょう。Behaveはsteps/フォルダ内をスキャンするほど賢いので、管理しやすいように自由に整理してください。

4. アサーションのメッセージを惜しまない

JenkinsやGitHub ActionsなどのCI/CDシステムでは、明確なエラーログは万言の言い訳よりも価値があります。漠然としたエラーの代わりに、「エラー:ログインステップで200ではなく404が返されました」と記述しましょう。深夜にデバッグする際、過去の自分に感謝することになるはずです。

BDDを使うことは、単にバグを見つけるためだけではありません。「あなたが求めているものを正しく作っています」という信頼を顧客と築くための方法です。皆さんのプロジェクトでBehaveの導入が成功することを願っています!

Share: