127 lines
5.6 KiB
Bash
127 lines
5.6 KiB
Bash
|
|
#!/usr/bin/env bash
|
|||
|
|
# 列出所有 E2E 測試(從 _test.go 的 e2eStep(...) 呼叫撈)。
|
|||
|
|
# 對齊 docs/e2e-testing.md 的「測試覆蓋矩陣」;新增 / 修改 e2eStep 後重跑即可。
|
|||
|
|
set -euo pipefail
|
|||
|
|
|
|||
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|||
|
|
TESTS_DIR="${ROOT}/test/e2e"
|
|||
|
|
|
|||
|
|
if ! command -v rg >/dev/null 2>&1; then
|
|||
|
|
echo "需要 ripgrep(brew install ripgrep)" >&2
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# Colors(非 TTY 時關掉)
|
|||
|
|
if [[ -t 1 ]]; then
|
|||
|
|
BOLD=$'\033[1m'; DIM=$'\033[2m'; CYAN=$'\033[36m'; YELLOW=$'\033[33m'; RESET=$'\033[0m'
|
|||
|
|
else
|
|||
|
|
BOLD=""; DIM=""; CYAN=""; YELLOW=""; RESET=""
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
echo "${BOLD}Gateway E2E — 自動測試清單${RESET}"
|
|||
|
|
echo "${DIM}(執行:make e2e-full / make e2e-journey / make test-e2e;單測:go test -tags=e2e -run TestXxx)${RESET}"
|
|||
|
|
|
|||
|
|
# ─────────────────────────────────────────────────────────────
|
|||
|
|
# Section A: Contract tests(單 endpoint,由 e2eStep banner 撈)
|
|||
|
|
# ─────────────────────────────────────────────────────────────
|
|||
|
|
echo
|
|||
|
|
echo "${BOLD}${CYAN}═══ Contract tests(make e2e-full)═══${RESET}"
|
|||
|
|
echo "${DIM}單一 endpoint 驗 HTTP contract;可平行;每個 func 一個測試。${RESET}"
|
|||
|
|
|
|||
|
|
# 模組分組
|
|||
|
|
contract_module() {
|
|||
|
|
case "$(basename "$1")" in
|
|||
|
|
health_test.go) echo "Health" ;;
|
|||
|
|
auth_test.go) echo "Auth" ;;
|
|||
|
|
member_test.go) echo "Member" ;;
|
|||
|
|
permission_test.go) echo "Permission" ;;
|
|||
|
|
*) echo "Other" ;;
|
|||
|
|
esac
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
contract_count=0
|
|||
|
|
current_module=""
|
|||
|
|
while IFS= read -r line; do
|
|||
|
|
file="${line%%:*}"; rest="${line#*:}"
|
|||
|
|
lineno="${rest%%:*}"
|
|||
|
|
sig="${rest#*:}"
|
|||
|
|
fname="$(printf '%s' "$sig" | sed -E 's/^func (Test[A-Za-z0-9_]+).*/\1/')"
|
|||
|
|
|
|||
|
|
# 只看 contract test 檔(不含 journey_*)
|
|||
|
|
case "$(basename "$file")" in
|
|||
|
|
journey_*.go|journey.go) continue ;;
|
|||
|
|
esac
|
|||
|
|
|
|||
|
|
mod="$(contract_module "$file")"
|
|||
|
|
if [[ "$mod" != "$current_module" ]]; then
|
|||
|
|
echo
|
|||
|
|
echo " ${BOLD}── $mod ──${RESET}"
|
|||
|
|
current_module="$mod"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
step=$(awk -v start="$lineno" 'NR>=start && NR<=start+5 && /e2eStep\(t,/ { print; exit }' "$file")
|
|||
|
|
if [[ -z "$step" ]]; then
|
|||
|
|
printf " ${YELLOW}? %-40s${RESET} ${DIM}(no e2eStep banner)${RESET}\n" "$fname"
|
|||
|
|
continue
|
|||
|
|
fi
|
|||
|
|
id="$(printf '%s' "$step" | sed -nE 's/.*e2eStep\(t, "([^"]*)", *"([^"]*)", *"([^"]*)", *"([^"]*)"\).*/\1/p')"
|
|||
|
|
method="$(printf '%s' "$step" | sed -nE 's/.*e2eStep\(t, "([^"]*)", *"([^"]*)", *"([^"]*)", *"([^"]*)"\).*/\2/p')"
|
|||
|
|
path="$(printf '%s' "$step" | sed -nE 's/.*e2eStep\(t, "([^"]*)", *"([^"]*)", *"([^"]*)", *"([^"]*)"\).*/\3/p')"
|
|||
|
|
desc="$(printf '%s' "$step" | sed -nE 's/.*e2eStep\(t, "([^"]*)", *"([^"]*)", *"([^"]*)", *"([^"]*)"\).*/\4/p')"
|
|||
|
|
|
|||
|
|
printf " ${BOLD}[%-9s]${RESET} %-7s %-50s %s\n" "$id" "$method" "$path" "$desc"
|
|||
|
|
printf " ${DIM}└─ %s${RESET}\n" "$fname"
|
|||
|
|
contract_count=$((contract_count+1))
|
|||
|
|
done < <(rg -n --no-heading '^func Test[A-Za-z0-9_]+\(t \*testing\.T\)' "${TESTS_DIR}" -t go)
|
|||
|
|
|
|||
|
|
# ─────────────────────────────────────────────────────────────
|
|||
|
|
# Section B: Journeys(k6 風格多步驟)
|
|||
|
|
# ─────────────────────────────────────────────────────────────
|
|||
|
|
echo
|
|||
|
|
echo "${BOLD}${CYAN}═══ Journeys(make e2e-journey)═══${RESET}"
|
|||
|
|
echo "${DIM}多步驟 user flow,共享狀態;任一步 fail 自動 skip 後續;用 NewJourney() + j.Step()。${RESET}"
|
|||
|
|
|
|||
|
|
journey_count=0
|
|||
|
|
journey_step_total=0
|
|||
|
|
while IFS= read -r line; do
|
|||
|
|
file="${line%%:*}"; rest="${line#*:}"
|
|||
|
|
lineno="${rest%%:*}"
|
|||
|
|
sig="${rest#*:}"
|
|||
|
|
fname="$(printf '%s' "$sig" | sed -E 's/^func (Test[A-Za-z0-9_]+).*/\1/')"
|
|||
|
|
|
|||
|
|
case "$(basename "$file")" in
|
|||
|
|
journey_*.go) : ;;
|
|||
|
|
*) continue ;;
|
|||
|
|
esac
|
|||
|
|
|
|||
|
|
# 抓 NewJourney(t, "J-1", "title")
|
|||
|
|
jline=$(awk -v start="$lineno" 'NR>=start && NR<=start+3 && /NewJourney\(t,/ { print; exit }' "$file")
|
|||
|
|
jid="$(printf '%s' "$jline" | sed -nE 's/.*NewJourney\(t, "([^"]*)", *"([^"]*)"\).*/\1/p')"
|
|||
|
|
jtitle="$(printf '%s' "$jline" | sed -nE 's/.*NewJourney\(t, "([^"]*)", *"([^"]*)"\).*/\2/p')"
|
|||
|
|
if [[ -z "$jid" ]]; then
|
|||
|
|
jid="?"; jtitle="(no NewJourney call)"
|
|||
|
|
fi
|
|||
|
|
steps="$(rg -n '\s+j\.(Step|SkipStep)\(' "$file" 2>/dev/null | wc -l | tr -d ' ')"
|
|||
|
|
echo
|
|||
|
|
printf " ${BOLD}[%s] %s${RESET} ${DIM}(%d steps · %s)${RESET}\n" "$jid" "$jtitle" "$steps" "$fname"
|
|||
|
|
|
|||
|
|
# 列出每個 step 的 id + desc
|
|||
|
|
rg -oN 'j\.(Step|SkipStep)\("[^"]+",\s*"[^"]+"' "$file" 2>/dev/null \
|
|||
|
|
| sed -nE 's/.*j\.(Step|SkipStep)\("([^"]+)", *"([^"]+)".*/\1|\2|\3/p' \
|
|||
|
|
| awk -F'|' -v jid="$jid" -v reset="$RESET" -v yellow="$YELLOW" '
|
|||
|
|
{
|
|||
|
|
kind=$1; sid=$2; desc=$3
|
|||
|
|
marker = (kind == "SkipStep") ? "⊘" : "▶"
|
|||
|
|
color = (kind == "SkipStep") ? yellow : ""
|
|||
|
|
printf " %s%s [%s.%s]%s %s\n", color, marker, jid, sid, reset, desc
|
|||
|
|
}
|
|||
|
|
'
|
|||
|
|
|
|||
|
|
journey_count=$((journey_count+1))
|
|||
|
|
journey_step_total=$((journey_step_total+steps))
|
|||
|
|
done < <(rg -n --no-heading '^func Test[A-Za-z0-9_]+\(t \*testing\.T\)' "${TESTS_DIR}" -t go)
|
|||
|
|
|
|||
|
|
# ─────────────────────────────────────────────────────────────
|
|||
|
|
echo
|
|||
|
|
echo "${DIM}合計:${contract_count} 個 contract tests · ${journey_count} 個 journeys (${journey_step_total} steps)${RESET}"
|