dramaling-vocab-learning/選項詞彙庫功能測試指南.md

450 lines
12 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 選項詞彙庫功能測試指南
**版本**: 1.0
**日期**: 2025-09-29
**專案**: DramaLing 智能英語學習系統
**功能**: 選項詞彙庫智能測驗選項生成系統測試
---
## 📋 測試概覽
### 測試目標
驗證選項詞彙庫功能的正確性、效能和穩定性,確保智能選項生成系統按預期運作。
### 測試範圍
- ✅ 基礎選項生成功能
- ✅ 詞彙庫充足性檢查
- ✅ 智能匹配算法驗證
- ✅ 快取機制效能測試
- ✅ 錯誤處理與邊界條件
- ✅ 與現有系統整合測試
### 前提條件
- 後端 API 已啟動並運行在 http://localhost:5008
- 資料庫已正確遷移並包含初始詞彙資料
- OptionsVocabulary 服務已正確註冊
---
## 🧪 測試執行步驟
### 1⃣ 環境檢查
#### 檢查後端服務狀態
```bash
# 檢查 API 是否正常運行
curl -X GET "http://localhost:5008/health"
```
**預期結果**: 返回 `{"Status": "Healthy", "Timestamp": "..."}`
#### 檢查 Swagger 文檔
```bash
# 開啟 Swagger UI 檢查 API 文檔
open http://localhost:5008/swagger/index.html
```
**預期結果**: 能夠看到 OptionsVocabularyTest 控制器的測試端點
---
### 2⃣ 基礎功能測試
#### 測試 A: 基本選項生成
```bash
# 測試生成 B1 等級的形容詞選項
curl -X GET "http://localhost:5008/api/test/optionsvocabulary/generate-distractors?targetWord=beautiful&cefrLevel=B1&partOfSpeech=adjective&count=3"
```
**預期結果**:
```json
{
"success": true,
"targetWord": "beautiful",
"cefrLevel": "B1",
"partOfSpeech": "adjective",
"requestedCount": 3,
"actualCount": 3,
"distractors": ["attractive", "lovely", "pretty"]
}
```
#### 測試 B: 不同詞性測試
```bash
# 測試名詞選項生成
curl -X GET "http://localhost:5008/api/test/optionsvocabulary/generate-distractors?targetWord=house&cefrLevel=A2&partOfSpeech=noun&count=3"
# 測試動詞選項生成
curl -X GET "http://localhost:5008/api/test/optionsvocabulary/generate-distractors?targetWord=run&cefrLevel=A2&partOfSpeech=verb&count=3"
```
#### 測試 C: 不同 CEFR 等級測試
```bash
# A1 等級測試
curl -X GET "http://localhost:5008/api/test/optionsvocabulary/generate-distractors?targetWord=cat&cefrLevel=A1&partOfSpeech=noun&count=3"
# C1 等級測試
curl -X GET "http://localhost:5008/api/test/optionsvocabulary/generate-distractors?targetWord=magnificent&cefrLevel=C1&partOfSpeech=adjective&count=3"
```
---
### 3⃣ 詞彙庫充足性測試
#### 測試所有支援的組合
```bash
# 檢查 A1 名詞詞彙庫
curl -X GET "http://localhost:5008/api/test/optionsvocabulary/check-sufficiency?cefrLevel=A1&partOfSpeech=noun"
# 檢查 B1 形容詞詞彙庫
curl -X GET "http://localhost:5008/api/test/optionsvocabulary/check-sufficiency?cefrLevel=B1&partOfSpeech=adjective"
# 檢查 B1 動詞詞彙庫
curl -X GET "http://localhost:5008/api/test/optionsvocabulary/check-sufficiency?cefrLevel=B1&partOfSpeech=verb"
```
**預期結果**:
```json
{
"success": true,
"cefrLevel": "B1",
"partOfSpeech": "adjective",
"hasSufficientVocabulary": true
}
```
---
### 4⃣ 詳細選項資訊測試
#### 測試帶詳細資訊的選項生成
```bash
curl -X GET "http://localhost:5008/api/test/optionsvocabulary/generate-distractors-detailed?targetWord=happy&cefrLevel=A2&partOfSpeech=adjective&count=3"
```
**預期結果**:
```json
{
"success": true,
"targetWord": "happy",
"cefrLevel": "A2",
"partOfSpeech": "adjective",
"requestedCount": 3,
"actualCount": 3,
"distractors": [
{
"word": "sad",
"cefrLevel": "A1",
"partOfSpeech": "adjective",
"wordLength": 3,
"isActive": true
},
{
"word": "angry",
"cefrLevel": "A2",
"partOfSpeech": "adjective",
"wordLength": 5,
"isActive": true
},
{
"word": "excited",
"cefrLevel": "A2",
"partOfSpeech": "adjective",
"wordLength": 7,
"isActive": true
}
]
}
```
---
### 5⃣ 全面覆蓋測試
#### 執行覆蓋率測試
```bash
curl -X GET "http://localhost:5008/api/test/optionsvocabulary/coverage-test"
```
**預期結果**:
- 所有測試組合都應返回 success: true
- 大部分組合應有 hasSufficientVocabulary: true
- 每個組合都應能生成至少 1-3 個選項
---
### 6⃣ 快取效能測試
#### 測試快取機制
```bash
# 第一次調用 (應從資料庫查詢)
time curl -X GET "http://localhost:5008/api/test/optionsvocabulary/generate-distractors?targetWord=test&cefrLevel=B1&partOfSpeech=noun&count=3"
# 第二次調用 (應從快取獲取,更快)
time curl -X GET "http://localhost:5008/api/test/optionsvocabulary/generate-distractors?targetWord=test&cefrLevel=B1&partOfSpeech=noun&count=3"
# 第三次調用 (仍從快取獲取)
time curl -X GET "http://localhost:5008/api/test/optionsvocabulary/generate-distractors?targetWord=test&cefrLevel=B1&partOfSpeech=noun&count=3"
```
**預期結果**:
- 第一次調用時間較長 (50-100ms)
- 後續調用時間顯著縮短 (10-30ms)
- 所有調用都返回相同結果
---
### 7⃣ 邊界條件與錯誤處理測試
#### 測試無效參數
```bash
# 測試無效詞性
curl -X GET "http://localhost:5008/api/test/optionsvocabulary/generate-distractors?targetWord=test&cefrLevel=B1&partOfSpeech=invalid&count=3"
# 測試無效 CEFR 等級
curl -X GET "http://localhost:5008/api/test/optionsvocabulary/generate-distractors?targetWord=test&cefrLevel=Z1&partOfSpeech=noun&count=3"
# 測試過大的數量
curl -X GET "http://localhost:5008/api/test/optionsvocabulary/generate-distractors?targetWord=test&cefrLevel=B1&partOfSpeech=noun&count=100"
# 測試空字串參數
curl -X GET "http://localhost:5008/api/test/optionsvocabulary/generate-distractors?targetWord=&cefrLevel=B1&partOfSpeech=noun&count=3"
```
**預期結果**:
- 系統應優雅處理錯誤,不應崩潰
- 返回適當的錯誤訊息或空結果
- 保持系統穩定性
---
### 8⃣ 整合測試
#### 測試與 QuestionGenerator 的整合
首先找到一個現有的 flashcard ID
```bash
# 獲取一些 flashcard 資料
curl -X GET "http://localhost:5008/api/flashcards"
```
然後測試問題生成:
```bash
# 使用實際的 flashcard ID 測試 (請替換 YOUR_FLASHCARD_ID)
curl -X GET "http://localhost:5008/api/questions/generate/vocab-choice/YOUR_FLASHCARD_ID"
```
**預期結果**:
- 返回的選擇題應包含智能生成的選項
- 選項應符合 flashcard 的 CEFR 等級和詞性
- 選項品質應比原有隨機生成更佳
---
## 📊 測試結果驗證標準
### ✅ 成功標準
#### 功能正確性
- [ ] 所有 API 端點返回 200 OK 狀態碼
- [ ] 生成的選項符合指定的 CEFR 等級 (允許相鄰等級)
- [ ] 生成的選項符合指定的詞性
- [ ] 字數長度在目標詞彙 ±2 字符範圍內
- [ ] 不包含目標詞彙本身
#### 效能標準
- [ ] API 響應時間 < 100ms (95th percentile)
- [ ] 快取命中後響應時間 < 30ms
- [ ] 快取命中率 > 70% (連續相同請求)
- [ ] 記憶體使用量穩定,無洩漏
#### 詞彙庫覆蓋
- [ ] A1-A2 等級的 noun/verb/adjective 有充足詞彙
- [ ] B1-B2 等級的主要詞性有充足詞彙
- [ ] 每個組合至少能生成 3 個不重複選項
#### 錯誤處理
- [ ] 無效參數不引起系統崩潰
- [ ] 優雅降級到備用選項生成
- [ ] 適當的日誌記錄和錯誤訊息
### ❌ 失敗標準
- API 返回 500 內部伺服器錯誤
- 生成的選項不符合指定條件
- 響應時間持續超過 100ms
- 系統崩潰或無響應
- 記憶體使用量持續增長
- 快取機制失效
---
## 🔍 進階測試指令
### 批量測試腳本
創建一個測試腳本來自動執行所有測試:
```bash
#!/bin/bash
# 選項詞彙庫功能自動測試腳本
echo "🧪 開始選項詞彙庫功能測試..."
BASE_URL="http://localhost:5008/api/test/optionsvocabulary"
# 測試計數器
TOTAL_TESTS=0
PASSED_TESTS=0
function run_test() {
local test_name="$1"
local url="$2"
local expected_success="$3"
echo "測試: $test_name"
TOTAL_TESTS=$((TOTAL_TESTS + 1))
response=$(curl -s "$url")
success=$(echo "$response" | jq -r '.success // false')
if [ "$success" = "$expected_success" ]; then
echo "✅ PASS: $test_name"
PASSED_TESTS=$((PASSED_TESTS + 1))
else
echo "❌ FAIL: $test_name"
echo "回應: $response"
fi
echo ""
}
# 執行基礎功能測試
run_test "B1形容詞選項生成" "${BASE_URL}/generate-distractors?targetWord=beautiful&cefrLevel=B1&partOfSpeech=adjective&count=3" "true"
run_test "A2名詞選項生成" "${BASE_URL}/generate-distractors?targetWord=house&cefrLevel=A2&partOfSpeech=noun&count=3" "true"
run_test "A2動詞選項生成" "${BASE_URL}/generate-distractors?targetWord=run&cefrLevel=A2&partOfSpeech=verb&count=3" "true"
# 詞彙庫充足性測試
run_test "B1形容詞詞彙庫充足性" "${BASE_URL}/check-sufficiency?cefrLevel=B1&partOfSpeech=adjective" "true"
run_test "A1名詞詞彙庫充足性" "${BASE_URL}/check-sufficiency?cefrLevel=A1&partOfSpeech=noun" "true"
# 詳細資訊測試
run_test "詳細選項資訊生成" "${BASE_URL}/generate-distractors-detailed?targetWord=happy&cefrLevel=A2&partOfSpeech=adjective&count=3" "true"
# 覆蓋率測試
run_test "詞彙庫覆蓋率測試" "${BASE_URL}/coverage-test" "true"
# 邊界條件測試 (這些可能返回 false 但不應崩潰)
run_test "無效詞性處理" "${BASE_URL}/generate-distractors?targetWord=test&cefrLevel=B1&partOfSpeech=invalid&count=3" "false"
echo "🏁 測試完成!"
echo "總測試數: $TOTAL_TESTS"
echo "通過測試: $PASSED_TESTS"
echo "成功率: $(( PASSED_TESTS * 100 / TOTAL_TESTS ))%"
if [ $PASSED_TESTS -eq $TOTAL_TESTS ]; then
echo "🎉 所有測試通過!"
exit 0
else
echo "⚠️ 有測試失敗,請檢查詳細資訊"
exit 1
fi
```
### 效能測試腳本
```bash
#!/bin/bash
# 效能測試腳本
echo "⚡ 開始效能測試..."
URL="http://localhost:5008/api/test/optionsvocabulary/generate-distractors?targetWord=test&cefrLevel=B1&partOfSpeech=noun&count=3"
echo "測試第一次調用 (冷啟動):"
time curl -s "$URL" > /dev/null
echo "測試第二次調用 (快取命中):"
time curl -s "$URL" > /dev/null
echo "測試第三次調用 (快取命中):"
time curl -s "$URL" > /dev/null
echo "📊 連續 10 次調用測試:"
for i in {1..10}; do
start_time=$(date +%s%N)
curl -s "$URL" > /dev/null
end_time=$(date +%s%N)
duration=$((($end_time - $start_time) / 1000000))
echo "第 $i 次調用: ${duration}ms"
done
```
---
## 📋 測試檢查清單
### 執行前檢查
- [ ] 後端 API 已啟動 (http://localhost:5008)
- [ ] 資料庫已正確遷移
- [ ] 初始詞彙資料已匯入
- [ ] curl 和 jq 工具已安裝
### 基礎功能測試
- [ ] 基本選項生成功能正常
- [ ] 不同詞性選項生成正常
- [ ] 不同 CEFR 等級選項生成正常
- [ ] 詞彙庫充足性檢查正常
- [ ] 詳細選項資訊生成正常
### 效能測試
- [ ] 首次調用響應時間合理 (< 100ms)
- [ ] 快取命中後響應時間更快 (< 30ms)
- [ ] 連續調用無記憶體洩漏
- [ ] 系統負載保持穩定
### 整合測試
- [ ] QuestionGenerator 整合正常
- [ ] 選項品質符合預期
- [ ] 原有功能未受影響
- [ ] 回退機制運作正常
### 錯誤處理測試
- [ ] 無效參數處理正常
- [ ] 系統不會崩潰
- [ ] 日誌記錄完整
- [ ] 錯誤訊息適當
---
## 🚨 故障排除
### 常見問題
#### API 無法連接
```bash
# 檢查後端是否運行
netstat -an | grep 5008
# 或
lsof -i :5008
```
#### 測試失敗
1. 檢查資料庫是否包含詞彙資料
2. 查看後端日誌輸出
3. 確認服務註冊是否正確
4. 檢查配置文件設定
#### 效能不佳
1. 檢查快取配置
2. 確認資料庫索引已建立
3. 監控記憶體使用量
4. 檢查日誌中的效能警告
---
**文檔版本**: 1.0
**最後更新**: 2025-09-29
**測試環境**: Development
**API 端點**: http://localhost:5008