# AI X BDD 讀書會 任務(一) 紀錄 > 使用 Windsurf 作為 AI Assistant,完成 AI 軟工研究會讀書會任務的完整過程。本文將以「實驗步驟」和「問題處理」兩個部分,重現從環境設定到功能迭代的流程。 :::info ## 實驗步驟 ::: ### 步驟一:Fork 專案與環境準備 1. **Fork 專案**:先將 GitHub 樣板專案 `Fork` 到自己的帳號下,再 `Clone` 到本機電腦。這確保了專案一開始就具備必要的設定檔與目錄結構。 2. **選擇 AI Assistant**:打開 VS Code,並選擇安裝 **Windsurf** 作為本次任務的 AI Assistant,準備開始進行 AI 驅動開發。 ### 步驟二:執行第一輪 BDD 流程 (基本訂單功能) 1. **下達初始指令**:一切準備就緒後,我們將讀書會示範用於指導 AI 進行 BDD 開發的關鍵 Prompt,貼給 Windsurf,觀察、感受一下 AI x BDD 的運行方式: ``` # Task 請你嚴格遵照「行為驅動開發 (BDD)」的方式,來完成 @order.feature 中所有驗收情境的開發。 不可同時進行 BDD 開發流程中多個步驟也不能略過任何一步驟,必須一步一步扎實執行並確認每一步的結果。 # Context ## Design Guideline - 參考 entities ERD: @ERD.png 以及 OOD 設計圖:@OOD.png 。兩張圖中所指示的類別屬性及操作只是基準,你可視情況增加新的類別、屬性或行為。 ## Tech Stack 1. Language Env:Java 2. BDD Test framework: Cucumber 3. Native test framework: Junit5 ## Application Environment 1. App 類型:純模組程式碼 2. 此 feature file 中的所有優惠邏輯存放至 OrderService 中 3. Source code root: src/ # BDD 開發流程 1. 先建置出 cucumber walking skeleton - 可順利運行 cucumber 以及至少一個 scenario ,確認至少有一個 test case 被 測試框架執行到。 2. 嚴格遵守 BDD 以及最小增量原則來開發所有程式碼,針對所有 scenario,一次開發一個 scenario,依序進行: A. 一次選擇一個 scenario 實作,除此 scenario 之外的測試全部都 ignore。撰寫此 scenario 對應的 Steps (given, when, then)、開啟相關類別,但是每個類別的行為都不實作,並且執行測試,確認測試失敗 (test fail),並且測試失敗的原因並非框架層級的錯誤,而是期望的「值」上的錯誤。嚴格確認這步驟完成後才能進行下一步的實作。 B. 為了通過上一步所撰寫的測試程式碼,請實作相關類別所需的程式碼,並確認能讓所有的測試程式碼都通過。請嚴格確認有執行到測試程式碼,從 test report 中覆述一次目前 test passed 的數量。 C. 遵守 clean code 原則,思考是否要重構每個類別的內部程式碼,如果必要重構的話,在重構完成之後,再執行一次測試,確保所有測試仍然通過,否則需修正邏輯直到測試全數通過。 ``` 2. **紅燈 (Red Light)**:AI 在分析後,決定採用 **Maven** 作為建置工具(詳見「問題處理」章節),並建立了 BDD 的「走路框架」(Walking Skeleton)。接著,它提議執行 `mvn test`,我們授權後,得到了一個預期中的、因為步驟未實作 (`PendingException`) 而產生的「紅燈」狀態。 3. **綠燈 (Green Light)**:接著,我們指示 AI 繼續實作功能。AI 修改了 `OrderService.java` 等檔案,加入了計算訂單總價的邏輯。再次執行 `mvn test` 後,測試成功通過,我們得到了一個漂亮的「綠燈」。 4. **重構 (Refactor)**:測試通過後,AI 馬上提出重構建議,希望能為所有 Java 類別加上 `package` 宣告,讓專案結構更標準化。我們接受了這個建議,AI 自動完成了程式碼的優化。至此,第一個使用者故事的開發循環宣告完成。 ### 步驟三:執行第二輪 BDD 流程 (迭代「雙十一優惠」) 1. **更新需求規格**:依照任務指示,將「雙十一優惠」的新規則,以 Gherkin 語法寫成三個新的 `Scenario`,並貼加到 `src/test/resources/features/order.feature` 檔案的末尾。 ```gherkin Scenario: 雙十一優惠 - 購買12件相同商品,其中10件打八折 Given a customer places an order with: | productName | quantity | unitPrice | | T-shirt | 12 | 100 | And the double-eleven promotion is enabled When the order is processed Then the order summary should be: | totalAmount | | 1000 | Scenario: 雙十一優惠 - 購買27件相同商品,其中20件打八折 Given a customer places an order with: | productName | quantity | unitPrice | | T-shirt | 27 | 100 | And the double-eleven promotion is enabled When the order is processed Then the order summary should be: | totalAmount | | 2300 | Scenario: 雙十一優惠 - 購買10件不同商品,沒有折扣 Given a customer places an order with: | productName | quantity | unitPrice | | T-shirt-A | 1 | 100 | | T-shirt-B | 1 | 100 | # ... (其他商品) And the double-eleven promotion is enabled When the order is processed Then the order summary should be: | totalAmount | | 1000 | ``` > :::info > **BDD 核心:Given-When-Then** > 上面的 `Scenario` (場景) 中使用的 `Given`, `When`, `Then` 是 BDD 的核心語法,它提供了一個描述系統行為的固定結構: > * **`Given (給定):`**描述測試開始前的**前置狀態**或**上下文**。它回答了:「在什麼樣的狀況下?」例如,`Given a customer places an order with...` (給定一位顧客下了一張訂單...)。 > * **`When (當):`**描述使用者執行的**具體動作**或發生的**某個事件**。它回答了:「當發生了什麼事?」例如,`When the order is processed` (當訂單被處理時...)。 > * **`Then (那麼):`**描述這個動作或事件發生後,我們**預期系統應該達成的結果**。它回答了:「那麼應該有什麼結果?」例如,`Then the order summary should be...` (那麼訂單的總結應該是...)。 > * **`And`**:用來連接多個 `Given`, `When`, 或 `Then`,讓語句更通順,它本身會繼承前一個關鍵字的類型。 > ::: 2. **再次啟動 BDD 流程**:將最初的 BDD Prompt 再次貼給 AI,要求它基於更新後的需求進行開發。 3. **紅燈與綠燈**:AI 在發現新的 `Scenario` 後,再次經歷了「紅燈」(因新步驟未實作而測試失敗)與「綠燈」(實作折扣邏輯後測試通過)的循環。過程中我們手動修正了一次 AI 生成的錯誤程式碼(詳見「問題處理」章節)。 4. **任務完成**:在 AI 完成雙十一折扣邏輯,並執行最終測試通過後,整個任務的程式開發部分宣告完成。 :::warning ## 問題處理 ::: ### 問題一:本機未安裝 Java 開發工具 (JDK) * **狀況描述**:AI 第一次試圖執行建置指令時,VS Code 回報 `No Java executable found`。 * #### **解決方案**: 1. 確認需要安裝 JDK。在 AI 提供的初始下載連結失效後,改用 **Adoptium** 作為下載來源。 2. 下載並安裝 OpenJDK 的 `.msi` 版本,並在安裝過程中勾選 `Add to PATH` 選項,將 Java 加入系統環境變數。 3. 完整重啟 VS Code,讓其能偵測到新安裝的 JDK。 ### 問題二:終端機 (PowerShell) 無法執行腳本 * **狀況描述**:在 Windows 預設的 `PowerShell` 終端機中,執行 `./gradlew` 指令時,系統回報「無法辨識...詞彙」。 * #### **解決方案**: 1. 確認問題來自 PowerShell 的安全策略。 2. 為避免修改全域設定,選擇更換 VS Code 的預設終端機。 3. 透過 `Ctrl + Shift + P` -> `Terminal: Select Default Profile`,將終端機從 `PowerShell` 切換為 `Command Prompt (cmd)`,成功解決了腳本執行問題。 ### 問題三:專案建置工具設定失敗 (Gradle -> Maven) * **狀況描述**:即便解決了終端機問題,執行 `gradlew.bat` 依然失敗,回報「不是內部或外部命令」。 * #### **解決方案**: 1. 執行 `dir` 指令,發現 `gradlew.bat` 檔案根本不存在。由此推斷,AI 最初建立專案框架的步驟就因缺少 JDK 而失敗了。 2. 在修正 JDK 問題後,用一個乾淨的狀態重新提交 BDD Prompt 給 AI。 3. AI 在這次嘗試中,展現了高度智能,**果斷放棄了先前一直失敗的 Gradle,轉而使用 Maven 來重建專案**,成功地讓建置流程步上正軌。 ### 問題四:AI 未能正確生成程式碼 * **狀況描述**:在開發第二個功能時,AI 未能為 `the double-eleven promotion is enabled` 這一新步驟產生對應的 Java 方法,且生成的 `import` 語法錯誤。 * #### **解決方案**: 1. 確認 AI 在此環節卡關,需要手動介入。 2. 由 AI 程式夥伴提供一份完整、修正過的 `OrderStepDefinitions.java` 程式碼。 3. 將 AI 生成的錯誤程式碼全部刪除,用提供的正確程式碼覆蓋,將開發流程拉回正軌。 ```java // 節錄手動修正的關鍵部分 // ... import 部分修正為 ... import main.java.Order; import main.java.OrderItem; import main.java.OrderService; public class OrderStepDefinitions { private Order order; private boolean doubleElevenPromotion = false; // 新增狀態變數 // ... 已存在的 @Disabled 方法 ... // // 手動補上的新步驟! // @And("the double-eleven promotion is enabled") public void the_double_eleven_promotion_is_enabled() { this.doubleElevenPromotion = true; throw new io.cucumber.java.PendingException(); } @When("the order is processed") public void the_order_is_processed() { // 空步驟,用於觸發流程 } } ``` :::success ## 總結與心得 ::: 這次的任務除了體驗BDD的開發模式之外,也透過解決問題的過程有了更多了解與收穫,並對AI目前的能力與侷限有更進一步的認知。 1. **環境建置**:一個正確、穩定的本地開發環境 (JDK、PATH) 是良好工作的基石。 2. **工具的兩面性**:AI Assistant 非常強大,它能自我修復(如 Gradle 換 Maven)、遵循複雜指令。但它並非完美,我們也遇到了 UI 沒刷新、程式碼產生錯誤等問題。 3. **人的價值**:作為開發者,我們的價值在於**診斷問題、提出假說、驗證假說**的能力。例如,透過 `dir` 指令發現檔案不存在,就是整個卡關過程的轉捩點。當 AI 卡住時,我們需要有能力介入並將其導回正軌。 4. **BDD 的力量**:`Given-When-Then` 的結構提供了一個非常清晰的藍圖和節奏。無論遇到什麼困難,我們的目標始終是回到「紅-綠-重構」這個循環上,這讓複雜的開發過程變得有條不紊。 可以說 AI 是強大的副駕駛,但工程師依然是重要的駕駛員。學會如何與 AI 更有效率進行協作分工,將是未來軟體工程師的核心競爭力之一。 --- ## 補充資料 > ### [使用 Chocolatey 安裝 Gradle] > >[https://hackmd.io/@862G4-mASVKG4SlsMaHffg/B1NwzX-Ixg](https://hackmd.io/@862G4-mASVKG4SlsMaHffg/B1NwzX-Ixg) ---
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up