--
date: 2025-10-10T00:00:00+08:00
researcher: Claude Code
git_commit: 34a6e2f3795e11b7d943be82eac142536a98a51f
branch: makefile
repository: fwauto
topic: "Init、Build、Flash 節點整合測試策略：從 Production 環境捕獲測試資料"
tags: [research, testing, integration-testing, makefile, build, flash, init]
status: complete
last_updated: 2025-10-10
last_updated_by: Claude Code

---

# Research: Init、Build、Flash 節點整合測試策略

**Date**: 2025-10-10T00:00:00+08:00
**Researcher**: Claude Code
**Git Commit**: 34a6e2f3795e11b7d943be82eac142536a98a51f
**Branch**: makefile
**Repository**: fwauto

## Research Question

如何對 FWAuto 的 init、build、flash 節點進行整合測試，使其更接近實際使用情景（而非單元測試），並從 production 環境捕獲真實的 make 執行結果作為測試資料？

## Summary

### 🔍 核心發現

1. **現有測試策略完全基於 Mock**：所有節點測試使用 `unittest.mock` 完全隔離 Makefile 執行，無真實整合測試
2. **Production 輸出捕獲機制缺失**：雖然節點實作有完整的日誌收集，但缺少將 production 輸出轉為測試資料的機制
3. **Makefile 契約式設計支援測試**：通過標準化的輸入/輸出契約（exit code + `build_output.toml`），Makefile 可被模擬或替換
4. **三種測試層次的可能性**：
   - **Layer 1 (現有)**：完全 Mock，快速但不驗證真實整合
   - **Layer 2 (缺少)**：使用測試用 Makefile 模擬真實行為（接近整合測試）
   - **Layer 3 (缺少)**：使用真實 Keil/ST-LINK 工具的完整整合測試

### 💡 關鍵洞察

通過建立 **測試用 Makefile** 來模擬 production 行為，可以在不依賴真實工具鏈的情況下，實現接近實際使用的整合測試。這些測試 Makefile 可以：

- 重播從 production 捕獲的輸出
- 模擬各種成功/失敗場景
- 驗證節點對真實輸出格式的處理能力

## Detailed Findings

### 1. 現有節點實作分析

#### Init 節點

**功能職責**：

```mermaid
graph LR
    A[檢查 .fwauto/ 存在] --> B[搜尋專案根目錄]
    B --> C[載入 config.toml]
    C --> D[初始化 Logging]
    D --> E[更新 State]
```

**關鍵實作位置**：

- **Graph Node**: `src/fwauto/nodes/init.py:11-57`
- **CLI Command**: `src/fwauto/cli_commands/init.py:53-122`

**State 變化**：
| 欄位 | 輸入 | 輸出 (成功) | 輸出 (失敗) |
|------|------|-------------|-------------|
| `project_initialized` | `False` | `True` | `False` |
| `project_root` | `""` | `/absolute/path` | `""` |
| `build_status` | `"pending"` | `"pending"` | `"error"` |
| `build_errors` | `[]` | `[]` | `[error_msg]` |

**測試特性**：

- ✅ 不依賴 Makefile，可完全模擬
- ✅ 主要驗證目錄結構和配置檔案
- ⚠️ 缺少驗證模板複製正確性的整合測試

#### Build 節點

**執行流程**：

```mermaid
graph TB
    Start[build_node] --> LoadConfig[載入 config.toml]
    LoadConfig --> BuildCmd[組成命令:<br/>make build PROJECT_ROOT=...]
    BuildCmd --> Popen[Popen 執行 subprocess]
    Popen --> Stream[即時輸出串流]
    Stream --> Wait[等待程序結束]
    Wait --> CheckExit{returncode == 0?}
    CheckExit -->|Yes| ReadToml[讀取 build_output.toml]
    CheckExit -->|No| Error[設定 error state]
    ReadToml --> Success[設定 success state]
    Success --> End[返回 State]
    Error --> End
```

**關鍵實作位置**: `src/fwauto/nodes/build.py:56-139`

**Makefile 互動方式**：

```python
# 命令組成
cmd = ["make", target, f"PROJECT_ROOT={project_root_path}"]

# 即時輸出
process = subprocess.Popen(
    cmd,
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,  # 合併 stderr
    text=True,
    cwd=str(makefile_dir),
    bufsize=1,  # Line buffered
)

# 逐行處理
for line in process.stdout:
    print(line, end="", flush=True)  # 即時顯示
    output_lines.append(line)        # 同時收集
```

**輸出處理**：

1. **Exit Code** → 判斷成功/失敗
2. **Stdout/Stderr** → 收集到 `build_log`
3. **build_output.toml** → 讀取 `hex_file` 路徑

**State 變化**：
| 狀態 | `build_status` | `build_errors` | `firmware_path` | `iteration` |
|------|----------------|----------------|-----------------|-------------|
| 成功 | `"success"` | `[]` | `/path/to.hex` | 不變 |
| 失敗 | `"error"` | `[error_msg]` | `None` | +1 |

#### Flash 節點

**執行流程與 Build 類似**：

```mermaid
graph TB
    Start[flash_node] --> LoadConfig[載入 config.toml]
    LoadConfig --> BuildCmd[組成命令:<br/>make flash PROJECT_ROOT=... HEX_FILE=...]
    BuildCmd --> Popen[Popen 執行 subprocess]
    Popen --> Stream[即時輸出串流]
    Stream --> Wait[等待程序結束]
    Wait --> CheckExit{returncode == 0?}
    CheckExit -->|Yes| Success[設定 success state]
    CheckExit -->|No| Error[設定 error state]
    Success --> End[返回 State]
    Error --> End
```

**關鍵實作位置**: `src/fwauto/nodes/flash.py:56-148`

**與 Build 的差異**：

- ❌ **不讀取輸出檔案**（不需要 `flash_output.toml`）
- ❌ **失敗不進入 AI 修復循環**（硬體問題無法自動修復）
- ✅ **僅依賴 exit code 判斷**

**已知 Bug**: `flash.py:130` 使用未定義變數 `result.returncode`（應為 `process.returncode`）

### 2. 現有測試策略分析

#### 測試架構

**測試檔案組織**：

```
tests/
├── test_utils.py                           # 工具函數測試
├── test_story_001_state_expansion.py       # State 定義測試
├── test_story_003_prompt_template.py       # Template 測試
├── test_story_004_log_analysis_node.py     # Log 節點測試
├── test_story_005_workflow_integration.py  # 工作流程整合測試
├── test_story_006_error_handling.py        # 錯誤處理測試
└── nodes/
    ├── test_build_makefile.py              # Build 節點測試
    └── test_flash_makefile.py              # Flash 節點測試
```

#### Mock 策略

**典型測試模式** (`test_build_makefile.py` 範例)：

```python
@patch("fwauto.nodes.build.load_toml")         # Mock 配置讀取
@patch("fwauto.nodes.build.subprocess.run")    # Mock subprocess
@patch("fwauto.nodes.build.Path")              # Mock 檔案系統
@patch("fwauto.nodes.build.os.path.getsize")   # Mock 檔案大小
def test_build_node_success(...):
    # 1. Mock 配置檔案
    mock_load_toml.side_effect = [
        {"build": {"makefile": "...", "target": "build"}},
        {"output": {"hex_file": "/test.hex"}},
    ]

    # 2. Mock subprocess 成功執行
    mock_subprocess.return_value = Mock(
        returncode=0,
        stdout="Build successful",
        stderr=""
    )

    # 3. 執行節點
    result = build_node(base_state)

    # 4. 驗證
    assert result["build_status"] == "success"
```

**Mock 涵蓋範圍**：

| 測試案例        | Build | Flash | 說明                |
| --------------- | ----- | ----- | ------------------- |
| 未初始化專案    | ✅    | ✅    | 驗證前置條件檢查    |
| 成功執行        | ✅    | ✅    | 驗證正常流程        |
| Config 不存在   | ✅    | ✅    | 驗證錯誤處理        |
| Makefile 不存在 | ✅    | ✅    | 驗證檔案檢查        |
| Make 執行失敗   | ✅    | ✅    | 驗證 exit code 處理 |
| 輸出檔案問題    | ✅    | ✅    | 驗證 TOML 讀取      |

#### 測試資料來源

**目前狀況**：

- ❌ **無專用測試資料目錄**（無 `tests/fixtures/`）
- ❌ **無 `conftest.py`** 全域 fixture 配置
- ✅ **內聯 Fixtures**：每個測試檔案定義自己的 `base_state`

**Fixture 範例**：

```python
@pytest.fixture
def base_state() -> FirmwareState:
    return {
        "user_prompt": "test build",
        "project_root": "/test/project",
        "project_initialized": True,
        "build_status": "pending",
        # ... 其他必要欄位
    }
```

**缺少的測試資料**：

- ❌ 真實 Keil 編譯輸出範例
- ❌ 真實 ST-LINK 燒錄輸出範例
- ❌ 各種錯誤情況的真實輸出
- ❌ Production `build_output.toml` 範例

### 3. Makefile 模板系統

#### 模板位置

**Production 模板**（實際使用）：

- Build: `src/fwauto/templates/build/Makefile.minimal`
- Flash: `src/fwauto/templates/flash/Makefile.minimal`

**文件範例**（參考用）：

- `docs/templates/build/Makefile.keil`
- `docs/templates/flash/Makefile.stlink`

#### Makefile 契約

**Build Makefile 契約** (`docs/makefile-contract.md`)：

```mermaid
graph LR
    A[輸入: PROJECT_ROOT] --> B[執行 Build]
    B --> C[輸出: Exit Code]
    B --> D[輸出: stdout/stderr]
    B --> E[輸出: build_output.toml]

    E --> F[必須包含:<br/>output.hex_file]
```

**契約要求**：

| 項目                     | 必須 | 說明                       |
| ------------------------ | ---- | -------------------------- |
| 接受 `PROJECT_ROOT` 參數 | ✅   | 透過命令列傳入             |
| Exit code 0 = 成功       | ✅   | 節點依此判斷成功/失敗      |
| Exit code != 0 = 失敗    | ✅   |                            |
| 輸出到 stdout/stderr     | ✅   | 節點捕獲作為 `build_log`   |
| 生成 `build_output.toml` | ✅   | 必須包含 `output.hex_file` |

**Flash Makefile 契約**：

| 項目                     | 必須 | 說明                        |
| ------------------------ | ---- | --------------------------- |
| 接受 `PROJECT_ROOT` 參數 | ✅   |                             |
| 接受 `HEX_FILE` 參數     | ⚠️   | 可選，或從 config 讀取      |
| Exit code 規範           | ✅   | 同 Build                    |
| 輸出到 stdout/stderr     | ✅   |                             |
| 生成輸出檔案             | ❌   | **不需要**（與 Build 不同） |

#### 模板結構

**Build Makefile 核心參數**：

```makefile
PROJECT_ROOT ?= ../..
KEIL_UV4 ?= C:\Keil_v5\UV4\UV4.exe
PROJECT_FILE ?= $(PROJECT_ROOT)/USER/UART.uvprojx
OUTPUT_DIR ?= $(PROJECT_ROOT)/OBJ
HEX_FILE ?= $(OUTPUT_DIR)/Template.hex

.PHONY: build

build:
    @"$(KEIL_UV4)" -b "$(PROJECT_FILE)" -j0
    @echo "✅ Build complete!"
```

**設計特性**：

- 所有參數使用 `?=` 提供預設值
- 支援透過環境變數覆蓋
- 相對路徑設計，適應不同專案

### 4. Production 輸出格式分析

#### 即時輸出機制

**實作位置**: `src/fwauto/nodes/build.py:84-103`

**輸出結構**：

```
Command: make build PROJECT_ROOT=/path/to/project
Working directory: /path/to/project/.fwauto/build
Exit code: 0
============================================================

[Makefile 的實際輸出...]
=== Building firmware ===
Project root: /path/to/project
Compiling with Keil...
[Keil 編譯器輸出...]
✅ Build complete!

✅ Build succeeded
```

**日誌組成**：

1. **Header**：命令、工作目錄、exit code
2. **分隔線**：60 個 `=`
3. **Makefile 輸出**：完整的 stdout/stderr
4. **結果訊息**：節點添加的成功/失敗訊息

#### Build 成功輸出範例

**典型結構**（基於模板推測）：

```
=== Building firmware ===
Project root: /absolute/path/to/project
Project file: /absolute/path/to/project/USER/UART.uvprojx

Compiling with Keil...
*** Using Compiler 'V5.06 update 7 (build 960)', folder: 'C:\Keil_v5\ARM\ARMCC\Bin'
Build target 'Template'
compiling delay.c...
compiling led.c...
compiling main.c...
compiling system_stm32f4xx.c...
compiling startup_stm32f40_41xxx.s...
linking...
Program Size: Code=1234 RO-data=567 RW-data=89 ZI-data=1024
"Template.axf" - 0 Error(s), 0 Warning(s).
✅ Build complete!
```

**關鍵標記**：

- `=== Building firmware ===` - 開始標記
- `0 Error(s), 0 Warning(s)` - Keil 成功標記
- `✅ Build complete!` - Makefile 成功標記

#### Build 失敗輸出範例

**典型錯誤輸出**：

```
=== Building firmware ===
Project root: /absolute/path/to/project

Compiling with Keil...
compiling main.c...
main.c(10): error:  #5: cannot open source input file "missing_header.h"
"Template.axf" - 1 Error(s), 0 Warning(s).
make: *** [build] Error 1
```

**關鍵標記**：

- `error:` - Keil 錯誤標記
- `X Error(s)` - 錯誤計數 > 0
- `make: *** [target] Error N` - Make 失敗標記

#### Flash 輸出範例

**成功輸出**（ST-LINK）：

```
=== Flashing firmware ===
Project root: /path/to/project
Hex file: /path/to/project/OBJ/Template.hex

STM32 ST-LINK CLI v3.9.0.0
STM32 ST-LINK Command Line Interface

ST-LINK SN  : 066DFF575251897267134338
ST-LINK FW  : V2J37S7
Board       : --
Voltage     : 3.24V
Device ID   : 0x0413 (STM32F407xx)
Flash size  : 1024 KBytes
RAM size    : 192 KBytes

Programming...
File downloaded successfully
Verification...OK
✅ Flash complete!
```

**失敗輸出**：

```
=== Flashing firmware ===

Error: No ST-LINK detected!
Please check your hardware connection.
make: *** [flash] Error 1
```

### 5. 技術可行性分析

#### 方向 1: 使用測試用 Makefile 模擬真實行為

**核心概念**：建立可控的 Makefile 來重播 production 行為

**實作方式**：

```makefile
# tests/fixtures/makefiles/build_success.mk
PROJECT_ROOT ?= ../..

.PHONY: build

build:
    @cat $(MAKEFILE_DIR)/../outputs/keil_build_success.txt
    @echo "status = \"success\"" > $(PROJECT_ROOT)/.fwauto/build_output.toml
    @echo "[output]" >> $(PROJECT_ROOT)/.fwauto/build_output.toml
    @echo "hex_file = \"$(PROJECT_ROOT)/OBJ/Template.hex\"" >> $(PROJECT_ROOT)/.fwauto/build_output.toml
    @exit 0
```

**優點**：

- ✅ 不依賴真實工具鏈（Keil、ST-LINK）
- ✅ 可重播從 production 捕獲的真實輸出
- ✅ 完全可控的測試環境（成功/失敗場景）
- ✅ 驗證節點對真實輸出格式的解析能力
- ✅ 快速執行（接近單元測試速度）

**限制**：

- ⚠️ 無法驗證真實工具鏈整合
- ⚠️ 需要維護測試輸出資料

#### 方向 2: 從 Production 捕獲輸出

**核心概念**：在真實環境執行一次，捕獲所有輸出作為測試資料

**可捕獲的資料**：

| 資料類型          | 來源         | 儲存位置建議                                       |
| ----------------- | ------------ | -------------------------------------------------- |
| Keil 成功輸出     | 真實 build   | `tests/fixtures/outputs/keil_build_success.txt`    |
| Keil 錯誤輸出     | 故意引入錯誤 | `tests/fixtures/outputs/keil_build_error_*.txt`    |
| ST-LINK 成功輸出  | 真實 flash   | `tests/fixtures/outputs/stlink_flash_success.txt`  |
| ST-LINK 錯誤輸出  | 硬體斷線測試 | `tests/fixtures/outputs/stlink_flash_error_*.txt`  |
| build_output.toml | 成功 build   | `tests/fixtures/configs/build_output_success.toml` |

**捕獲方式**：

1. **手動捕獲**：

   ```bash
   fwauto build 04 2>&1 | tee tests/fixtures/outputs/real_build_$(date +%Y%m%d).txt
   ```

2. **自動捕獲模式**（可能的實作方向）：
   ```python
   # 在節點中加入捕獲模式
   if os.getenv("FWAUTO_CAPTURE_MODE"):
       capture_path = Path("tests/fixtures/outputs/captured_output.txt")
       capture_path.write_text(full_output)
   ```

#### 方向 3: 真實整合測試

**核心概念**：在 CI/CD 或開發環境中使用真實工具鏈

**適用場景**：

- 驗證與新版本 Keil 的相容性
- 驗證與不同 ST-LINK 韌體的相容性
- 回歸測試

**實作方式**：

```python
@pytest.mark.integration
@pytest.mark.skipif(not has_keil(), reason="Requires Keil toolchain")
def test_real_build():
    """使用真實 Keil 進行整合測試"""
    # 使用真實的測試專案
    # 執行真實的 fwauto build
    # 驗證實際產生的 hex 檔案
```

**限制**：

- ⚠️ 需要安裝真實工具鏈（Keil 授權費用高）
- ⚠️ 執行時間長
- ⚠️ 硬體依賴（Flash 測試需要實際硬體）

### 6. 測試層次架構建議

```mermaid
graph TB
    subgraph Layer3[Layer 3: 真實整合測試]
        RealKeil[真實 Keil 編譯]
        RealFlash[真實 ST-LINK 燒錄]
        RealHW[實際硬體驗證]
    end

    subgraph Layer2[Layer 2: 模擬整合測試]
        TestMakefile[測試用 Makefile]
        ReplayOutput[重播 Production 輸出]
        VerifyParsing[驗證輸出解析]
    end

    subgraph Layer1[Layer 1: 單元測試 - 現有]
        MockSubprocess[Mock subprocess]
        MockFS[Mock 檔案系統]
        UnitTest[快速驗證邏輯]
    end

    Layer1 --> Layer2
    Layer2 --> Layer3

    style Layer1 fill:#d4edda
    style Layer2 fill:#fff3cd
    style Layer3 fill:#f8d7da
```

**各層次特性**：

| 層次           | 執行速度 | 真實性          | 依賴        | 適用場景         |
| -------------- | -------- | --------------- | ----------- | ---------------- |
| Layer 1 (現有) | 🚀 極快  | ⭐ 低           | 無          | 開發期間快速驗證 |
| Layer 2 (建議) | 🏃 快    | ⭐⭐⭐ 中高     | 測試資料    | CI/CD、回歸測試  |
| Layer 3 (可選) | 🐢 慢    | ⭐⭐⭐⭐⭐ 最高 | 工具鏈+硬體 | Release 前驗證   |

## Architecture Insights

### 節點的契約式設計

FWAuto 節點與 Makefile 之間採用 **契約式設計 (Design by Contract)**：

```mermaid
graph LR
    Node[FWAuto Node] -->|提供: PROJECT_ROOT| Makefile[Makefile]
    Makefile -->|返回: Exit Code| Node
    Makefile -->|返回: stdout/stderr| Node
    Makefile -->|返回: build_output.toml| Node

    style Node fill:#e3f2fd
    style Makefile fill:#fff3e0
```

**設計優勢**：

- ✅ **工具無關**：可支援任何 toolchain（Keil、GCC、IAR 等）
- ✅ **可測試性**：契約明確，易於建立測試替身 (Test Double)
- ✅ **可替換性**：測試時可用簡單 Makefile 替換複雜 Makefile

**測試啟示**：

- 💡 可建立符合契約的「測試用 Makefile」
- 💡 測試用 Makefile 可重播真實輸出
- 💡 驗證節點是否正確處理契約規範的所有情況

### 即時輸出的雙重用途

**實作機制**（`subprocess.Popen` + line buffering）：

```python
# 逐行處理輸出
for line in process.stdout:
    print(line, end="", flush=True)  # 用途 1: 使用者體驗
    output_lines.append(line)        # 用途 2: 測試資料來源
```

**雙重價值**：

1. **生產環境**：提供即時回饋給使用者
2. **測試環境**：完整日誌可作為測試資料來源

**測試啟示**：

- 💡 Production 執行本身就在生成測試資料
- 💡 可建立「捕獲模式」自動保存輸出
- 💡 累積的真實輸出可建立測試資料庫

### State-based 測試模式

**LangGraph State 作為測試界面**：

```mermaid
graph LR
    Input[Input State] --> Node[Node Function]
    Node --> Output[Output State]

    Test[Test] -->|準備| Input
    Test -->|驗證| Output
```

**優勢**：

- ✅ 測試不依賴內部實作細節
- ✅ State 是 TypedDict，有明確型別定義
- ✅ 易於建立測試 fixture（標準 dict）

**測試啟示**：

- 💡 可建立「State 快照」作為測試資料
- 💡 測試只需驗證 State 變化是否符合預期
- 💡 支援 Property-based Testing（如使用 Hypothesis）

### 錯誤處理的三層驗證

**Build 節點的驗證層次**：

```mermaid
graph TB
    Execute[執行 Make] --> Check1{Exit Code}
    Check1 -->|!= 0| Fail1[立即失敗]
    Check1 -->|== 0| Check2{build_output.toml 存在?}
    Check2 -->|No| Fail2[失敗: 缺少輸出]
    Check2 -->|Yes| Check3{HEX 檔案存在?}
    Check3 -->|No| Fail3[失敗: HEX 不存在]
    Check3 -->|Yes| Success[成功]

    style Success fill:#d4edda
    style Fail1 fill:#f8d7da
    style Fail2 fill:#f8d7da
    style Fail3 fill:#f8d7da
```

**測試啟示**：

- 💡 測試需涵蓋所有三層驗證
- 💡 每一層失敗的錯誤訊息應該不同
- 💡 測試用 Makefile 可模擬各層失敗情況

## Code References

### 核心節點實作

| 檔案路徑                          | 行號   | 說明                                 |
| --------------------------------- | ------ | ------------------------------------ |
| `src/fwauto/nodes/init.py`        | 11-57  | Init 節點 - 搜尋專案並載入配置       |
| `src/fwauto/cli_commands/init.py` | 53-122 | Init 命令 - 建立目錄與複製模板       |
| `src/fwauto/nodes/build.py`       | 56-139 | Build 節點 - Makefile 執行與輸出處理 |
| `src/fwauto/nodes/flash.py`       | 56-148 | Flash 節點 - 燒錄執行                |
| `src/fwauto/config.py`            | 44-126 | 配置管理 - ProjectConfig 類別        |
| `src/fwauto/state.py`             | 1-50   | FirmwareState TypedDict 定義         |

### 關鍵實作細節

| 功能                   | 位置               | 說明                         |
| ---------------------- | ------------------ | ---------------------------- |
| 即時輸出機制           | `build.py:84-103`  | Popen + line buffering       |
| Exit Code 判斷         | `build.py:116-139` | 成功/失敗分支處理            |
| build_output.toml 讀取 | `build.py:125-126` | 取得 hex_file 路徑           |
| Makefile 命令組成      | `build.py:71-79`   | make + target + PROJECT_ROOT |
| Flash Bug              | `flash.py:130`     | 使用未定義變數 `result`      |

### 測試檔案

| 檔案路徑                                       | 行號範圍 | 測試內容                   |
| ---------------------------------------------- | -------- | -------------------------- |
| `tests/nodes/test_build_makefile.py`           | 全部     | Build 節點 6 個測試案例    |
| `tests/nodes/test_flash_makefile.py`           | 全部     | Flash 節點 7 個測試案例    |
| `tests/test_story_005_workflow_integration.py` | 全部     | LangGraph 工作流程整合測試 |

### Makefile 模板

| 檔案路徑                                      | 說明                        |
| --------------------------------------------- | --------------------------- |
| `src/fwauto/templates/build/Makefile.minimal` | Production Build 模板       |
| `src/fwauto/templates/flash/Makefile.minimal` | Production Flash 模板       |
| `docs/templates/build/Makefile.keil`          | Keil 完整範例（含錯誤處理） |
| `docs/templates/flash/Makefile.stlink`        | ST-LINK 完整範例            |

### 文件參考

| 檔案路徑                    | 內容              |
| --------------------------- | ----------------- |
| `docs/makefile-contract.md` | Makefile 契約規範 |
| `docs/makefile-design.md`   | Makefile 設計文件 |
| `docs/templates/README.md`  | 模板使用指南      |

## Open Questions

### 測試資料管理

1. **測試資料版本控制**：
   - 應該 commit 真實的 Keil 輸出到 git 嗎？
   - 如果輸出很長（幾 KB），是否需要壓縮或摘要？

2. **多版本工具鏈**：
   - 是否需要維護多個版本的 Keil 輸出（如 V5.06 vs V5.37）？
   - 如何處理工具鏈版本變更導致的輸出格式變化？

3. **測試資料更新策略**：
   - 當 Makefile 模板更新時，如何更新測試資料？
   - 是否需要自動化的「重新捕獲」流程？

### 測試執行環境

4. **跨平台測試**：
   - 目前實作假設 Windows 環境（Keil、ST-LINK 路徑）
   - 如何在 Linux CI/CD 環境中執行測試？
   - 是否需要條件式跳過某些測試？

5. **CI/CD 整合**：
   - GitHub Actions 是否需要安裝 make？
   - 測試用 Makefile 是否相容於 Linux 的 make？

### 測試策略

6. **測試涵蓋範圍**：
   - 是否需要測試所有可能的 Keil 錯誤類型？
   - Flash 硬體錯誤的情況如何模擬？

7. **效能 vs 真實性**：
   - Layer 2 測試（測試用 Makefile）是否足夠？
   - 何時需要執行 Layer 3 測試（真實工具鏈）？

8. **測試資料組織**：
   - 是否應該建立 `tests/fixtures/` 目錄結構？
   - 如何組織不同場景的測試資料（成功/各種失敗類型）？

### 實作細節

9. **Flash 節點 Bug**：
   - `flash.py:130` 的 bug 修復優先級為何？
   - 是否有其他類似的未發現 bug？

10. **日誌系統**：
    - Production 日誌是否已經在自動收集？
    - 日誌檔案位置在哪裡（`.fwauto/logs/`）？
    - 是否可直接從日誌提取測試資料？

### 未來擴展

11. **其他節點**：
    - Log 節點是否也需要類似的整合測試策略？
    - AI Brain 節點如何測試？

12. **State 持久化**：
    - 是否需要測試 State 的序列化/反序列化？
    - Checkpoint 機制是否需要專門的測試？

## Related Research

目前 `.ai/rpi/research/` 目錄中尚無相關研究文件。本研究為首份關於測試策略的文件。

**建議後續研究**：

- `2025-XX-XX-test-makefile-implementation.md` - 測試用 Makefile 的具體實作
- `2025-XX-XX-ci-cd-testing-strategy.md` - CI/CD 環境的測試策略
- `2025-XX-XX-log-analysis-testing.md` - Log 節點的測試策略
