0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

動いているコードが正解だった:AIで逆Gherkin化して仕様を可視化した話

Posted at

はじめに(Why)

数年運用している業務システムで、ずっとモヤっとしていた問題がありました。

  • 機能は動いているが 仕様書がない
  • 「これは仕様?それともたまたま?」がコードを読まないと分からない
  • 特に 例外系・権限・二重処理 で、担当者ごとに解釈が違う

今回対象にしたのは「ポイント交換」機能です。

  • 複数の交換先がある
  • 最小/最大、換算率、権限など制約が多い
  • 外部連携失敗時の扱いが重要

正直、毎回コードを追うのはしんどく、
「人間が読める仕様」に落としたいと思いました。

ただし、現実は既存システム。
新規開発のように Gherkin から書くのは無理です。

そこで試したのが、AIを使った逆Gherkin化でした。


Gherkin / BDD とは(最小限)

  • Gherkin:Given / When / Then で振る舞いを書くフォーマット
  • BDD:仕様とテストの認識を揃える考え方

今回は 「テスト自動化」ではなく「仕様の可視化」 が目的です。
いきなり Behave / Cucumber を回すことはしません。


なぜ「逆Gherkin化」なのか

新規開発なら、

仕様 → Gherkin → 実装

が理想です。

でも既存システムでは、

実装(=事実) → 仕様

の方が現実的です。

  • 正解は「動いているコード」
  • 仕様書よりコードの方が新しい
  • 暗黙知を炙り出したい

逆Gherkin化は、既存システムにBDDを途中導入する現実解だと感じました。


対象にしたシステム(抽象化)

  • バックエンド:Python系API
  • フロント:Web / アプリ相当(別リポジトリ)
  • 機能:ポイント交換(複数の交換先)

この機能の特徴は、

  • 残高チェック
  • 最小 / 最大交換量
  • 換算レート(デバイス差あり)
  • 権限(購入・利用実績によって変化)
  • 二重処理防止
  • 外部連携失敗時のロールバック

仕様の塊みたいな機能でした。


実際にやった手順(How)

Step1:対象を絞る

最初から全部はやりません。

  • if / else が多い
  • ステータス分岐がある
  • 例外が多い

この条件に当てはまる 交換フロー1種類から始めました。


Step2:AIに「調査役」をやらせる

重要なのは プロンプト設計です。
「Gherkinにして」だけだと、ほぼ失敗します。

実務で使っている調査依頼プロンプト(汎用化)はこちらです。

あなたは既存システムの仕様調査担当です。
仕様書が存在しない「ポイント交換」機能について、コードから振る舞いを読み取り、
人間が理解できるようにGherkin(Given/When/Then)で列挙してください。

目的:
- 仕様の全体像と差分を把握する
- レビュー・合意可能な仕様書を作る

ルール:
- 技術用語(クラス名、DB、HTTPなど)は使わない
- ユーザー視点・業務視点で書く
- if/elseをそのまま列挙しない
- 正常系と代表的な異常系を含める
- 断定できない点は「要確認」と明示する

出力:
1) 発見した交換種類と制約
2) Gherkin(Feature / Scenario)
3) 要確認事項

ポイントは 「断定しない」「要確認を出させる」 です。


Before / After(ここが一番反応が良かった)

Before(擬似コード)

if not user.can_exchange:
    raise Forbidden

if amount < MIN_AMOUNT:
    raise ValidationError

if lock_exists(user_id):
    raise Conflict

deduct_points(user, amount)

try:
    external_grant(converted_amount)
except ExternalError:
    refund_points(user, amount)

After(Gherkin)

Feature: ポイントを外部サービスへ交換する

  Background:
    Given ログイン済みの会員である
    And ポイント交換が許可されている

  Scenario: 正常にポイントを交換できる
    Given 利用可能ポイントが1,000ptある
    When 500ptの交換を申請する
    Then 利用可能ポイントが500pt減る
    And 外部ポイントが付与される

  Scenario: 交換権限がない場合は交換できない
    Given ポイント交換が許可されていない
    When 交換を申請する
    Then 交換できない旨が表示される
    And ポイントは減らない

  Scenario: 外部付与に失敗した場合は元に戻る
    Given 交換申請が受け付けられている
    When 外部付与が失敗する
    Then ポイントは元に戻る
    And 利用者に失敗が分かる

コードでは「当たり前」だった分岐が、
仕様として初めて言語化されました。


やって分かった:AIは万能じゃない(Gotcha)

Gotcha1:内部仕様を仕様だと誤解する

  • TTL
  • リトライ回数
  • バッチタイミング

AIは全部 Then に書きたがります。

👉 Gherkinは「観測可能な結果」だけにする
👉 内部都合は「実装メモ」へ逃がす


Gotcha2:提供終了・移行中の機能が混ざる

画面では終了案内が出ているのに、
Scenario上は「普通に使える」扱いになっていました。

👉 @deprecated@disabled のタグで整理
👉 「現行 / 過去 / 移行中」を明示


Gotcha3:用語が揺れる

「残高」「利用可能」「付与」「交換」などが混在。

👉 用語を Feature冒頭で固定
👉 Glossaryを別途作成


なぜ最初からテストにしなかったのか

最初からBDDテストにすると、

  • 仕様が固まっていない
  • 要確認が多い
  • テストが壊れやすい

今回はあえて 「仕様の可視化」だけ に集中しました。

テスト化は、
合意が取れた Feature から段階的にで十分でした。


導入して得られた効果

  • 仕様確認が「コード読む」→「Scenario読む」に変わった
  • 例外系の認識ズレが減った
  • レビュー観点が整理されたことで、1件あたりのレビュー往復回数が
    • 逆Gherkin化前:平均3〜4往復
    • 逆Gherkin化後:平均1〜2往復
      程度に減りました(体感ベース)。
  • 新規メンバーのキャッチアップが楽になった

特に「これは仕様ですか?」という会話が
Gherkinを指差すだけで済むようになったのは大きかったです。


まとめ

  • 逆Gherkin化は 既存システムにBDDを入れる現実解
  • AIは「仕様の叩き台作成」に非常に強い
  • ただし レビューと要確認整理は人間必須
  • 全部やらず、重要フローだけで十分

もし既存コードの仕様化に悩んでいるなら、
テストを書く前に、逆Gherkin化を強くおすすめします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?