name: export-feature-file description: > 當使用者提供 Gherkin 文檔、業務邏輯說明或需求規格,並要求產出可被測試框架執行的 Feature File 時,必須載入此技能。 支援 .NET (Reqnroll)、Java (Cucumber-JVM)、JavaScript/TypeScript (Cucumber.js)、Python (Behave)、Flutter/Dart (flutter_gherkin) 等框架;清單外的框架以 LLM 通用知識產出 Step Definitions, 產出符合框架規範的 .feature 檔案,包含 Scenario、Scenario Outline、Examples 等結構。 觸發情境包含但不限於:「幫我產出 feature file」、「把這個轉成 .feature」、「export feature file」、 「根據業務邏輯寫 feature」、「建立測試案例檔」。 即使使用者只說「輸出 feature」或「新增 .feature 檔」,只要有提供業務邏輯或 Gherkin 內容,也應載入此技能。
Export Feature File
目的
產出可直接被 BDD 測試框架執行的 Feature File(.feature),實現「測試即文件」(Living Documentation)。
支援的測試框架
已知框架(有 reference 範例)
| 語言/平台 | 測試框架 | Cucumber Expression {} |
載入 Reference |
|---|---|---|---|
| .NET | Reqnroll | ✅ 原生支援 | references/dotnet-reqnroll-steps.cs |
| Java | Cucumber-JVM | ✅ 原生支援 | references/java-cucumber-steps.java |
| JavaScript/TypeScript | Cucumber.js | ✅ 原生支援 | references/typescript-cucumber-steps.ts |
| Python | Behave | ❌ 使用框架原生語法 | references/python-behave-steps.py |
| Flutter/Dart | flutter_gherkin | ✅ 原生支援 | references/dart-flutter-gherkin-steps.dart |
執行說明:
- 判別框架後,只讀取對應的 reference 檔作為 Step Definitions 風格依據
- Ruby (Cucumber)、Go (Godog) 已在 Cucumber Expression 表格列出,但無 reference,走 fallback
未知框架(fallback)
框架不在上表時,直接以 LLM 通用知識處理:
.feature檔案格式完全相同(Gherkin 格式與框架無關)- Step Definitions 依該框架的主流慣例產出
- 不需告知使用者
格式定義
Feature: 功能名稱
功能描述(說明這個功能的目的)
Scenario: 情境描述(單一固定案例)
Given 前置條件
When 觸發動作
Then 預期結果
Scenario Outline: 情境描述(多組測試資料)
Given 前置條件 <參數A>
When 觸發動作 <參數B>
Then 預期結果 <參數C>
Examples:
| 參數A | 參數B | 參數C |
| 值1 | 值2 | 值3 |
| 值4 | 值5 | 值6 |
| 關鍵字 | 用途 | 範例 |
|---|---|---|
| Feature | 功能名稱與描述 | Feature: 用戶登入 |
| Scenario | 單一固定測試案例 | Scenario: 用戶成功登入 |
| Scenario Outline | 參數化測試案例,搭配 Examples | Scenario Outline: 登入驗證 |
| Examples | 測試資料表格,搭配 Scenario Outline | 見範例 |
| Given | 前置條件 / 初始狀態 | Given 用戶已註冊帳號 "test@example.com" |
| When | 觸發的動作或事件 | When 用戶點擊登入按鈕 |
| Then | 預期的結果 | Then 系統導向至首頁 |
| And | 延續上一個關鍵字(可選) | And 顯示歡迎訊息 |
範例
範例 1:用戶登入
輸入(程式碼邏輯):
// 檢查帳號密碼,正確則導向首頁,錯誤則顯示錯誤訊息
// 連續錯誤 3 次則鎖定帳號
輸出(Feature File):
Feature: 用戶登入
用戶透過帳號密碼進行身份驗證,以存取系統功能
Scenario: 用戶成功登入
Given 用戶已註冊帳號 "test@example.com"
And 帳號未被鎖定
When 用戶輸入正確的帳號密碼
Then 系統導向至首頁
Scenario: 用戶登入失敗
Given 用戶已註冊帳號 "test@example.com"
When 用戶輸入錯誤的密碼
Then 系統停留在登入頁面
And 顯示錯誤訊息 "帳號或密碼錯誤"
Scenario Outline: 連續登入失敗鎖定帳號
Given 用戶已連續輸入錯誤密碼 <前次失敗> 次
When 用戶第 <本次> 次輸入錯誤密碼
Then 帳號狀態為 "<結果>"
Examples:
| 前次失敗 | 本次 | 結果 |
| 1 | 2 | 正常 |
| 2 | 3 | 鎖定 |
範例 2:購物車
輸入(需求描述):
用戶可以將商品加入購物車,數量不可超過庫存,
結帳時計算總金額並套用折扣碼
輸出(Feature File):
Feature: 購物車管理
用戶可以管理購物車內的商品,並在結帳時套用優惠
Scenario Outline: 加入商品至購物車
Given 商品庫存為 <庫存> 件
When 用戶將該商品加入購物車 <數量> 件
Then 購物車商品數量為 <數量>
And 庫存剩餘 <剩餘> 件
Examples:
| 庫存 | 數量 | 剩餘 |
| 10 | 1 | 9 |
| 10 | 5 | 5 |
Scenario: 加入商品超過庫存數量
Given 商品庫存為 5 件
When 用戶嘗試將該商品加入購物車 10 件
Then 系統拒絕此操作
And 顯示錯誤訊息 "庫存不足"
Scenario Outline: 套用折扣碼
Given 購物車總金額為 <原價> 元
And 折扣碼 "<折扣碼>" 可折抵 <折扣>%
When 用戶輸入折扣碼 "<折扣碼>"
Then 總金額更新為 <結果> 元
Examples:
| 原價 | 折扣碼 | 折扣 | 結果 |
| 1000 | SAVE10 | 10 | 900 |
| 1000 | SAVE20 | 20 | 800 |
輸出規範
- 必須包含 Feature:每個輸出都以 Feature 開頭,說明功能名稱與目的
- 相關 Scenario 歸屬同一 Feature:將相關的測試情境組織在同一個 Feature 下
- 每個 Scenario 聚焦於單一行為
- 專注在有價值的行為:不求詳盡,只描述最關鍵的業務規則
- 使用業務語言,但可提及 API、DB 等技術元素作為測試驗證點
- Given/When/Then 各自獨立成行,保持可讀性
- And 為可選,僅當條件或結果有多項時才使用
- 使用具體數值:提供實際的測試資料,不使用抽象變數
- 參數化測試使用 Scenario Outline:
- 當同一行為需要多組測試資料時,使用
Scenario Outline+Examples - 參數使用
<參數名稱>格式 - Examples 表格提供具體測試資料
- 當同一行為需要多組測試資料時,使用
- 字串參數用雙引號包覆:如
"test@example.com"、"SAVE10" - 沙漏原則 - When 最小化:
- When 越小越好,理想情況只有一行
- 將操作步驟移至 Given
- When 只保留最關鍵的觸發點
- 輸出後更新指定文檔:將產出的內容寫入用戶指定的
.feature檔案
Step Definitions 風格規範
Cucumber Expression(統一使用 {} 格式)
框架原生支援 Cucumber Expression 時,使用 {string}、{int} 等 {} 格式。
框架不原生支援時(如 Python Behave、PHP Behat),使用該框架的原生參數語法,不勉強套用。
| 比較項目 | Regex 格式(禁用) | Cucumber Expression 格式(採用) |
|---|---|---|
| 字串參數 | @"帳號 ""(.*)""" |
"帳號 {string}" |
| 整數參數 | @"共 (\d+) 筆" |
"共 {int} 筆" |
| 浮點數參數 | @"金額 ([\d.]+)" |
"金額 {float}" |
| 無參數 | @"用戶點擊登入" |
"用戶點擊登入" |
Step Definitions 對應提示
產出 Feature File 後,開發者需依據所使用的測試框架撰寫對應的 Step Definitions。
Scope 綁定規範
Step Definitions 必須透過 Scope 機制明確綁定至對應的 Feature,避免跨 Feature 的步驟定義衝突。
| 框架 | Scope 語法 | 範例 |
|---|---|---|
| .NET (Reqnroll) | [Scope(Feature = "Feature 名稱")] |
[Scope(Feature = "用戶登入")] |
| Java (Cucumber-JVM) | 不支援 Scope,透過 Glue 路徑區隔 | @CucumberOptions(glue = "steps.login") |
| JavaScript/TypeScript | 不支援 Scope,透過模組目錄區隔 | features/login/step_definitions/ |
| Python (Behave) | 不支援 Scope,透過 steps 目錄區隔 | features/steps/login_steps.py |
| Flutter/Dart (flutter_gherkin) | 不支援 Scope,在 runner config 集中註冊步驟 | FlutterTestConfiguration(stepDefinitions: [...]) |
Scope 的 Feature 名稱需與
.feature檔案中的Feature:標題完全一致。
Step Definitions 範例
判別框架後,讀取對應的 reference 檔案作為撰寫 Step Definitions 的風格依據:
- .NET (Reqnroll):
references/dotnet-reqnroll-steps.cs - Java (Cucumber-JVM):
references/java-cucumber-steps.java - JavaScript/TypeScript (Cucumber.js):
references/typescript-cucumber-steps.ts - Python (Behave):
references/python-behave-steps.py - Flutter/Dart (flutter_gherkin):
references/dart-flutter-gherkin-steps.dart
注意:產出 Step Definitions 前必須先讀取對應語言的 reference 檔案,確保遵循一致的風格與 Scope 綁定規範。
檔案命名規範
- 使用
.feature副檔名 - 檔名使用 PascalCase 或 kebab-case
- 範例:
UserLogin.feature、shopping-cart.feature