#!/usr/bin/env bash # Flaky test scanner — 连续运行测试检测不稳定测试 # 用法: # bash scripts/flaky-scan.sh # 随机顺序运行 3 次全量测试 # bash scripts/flaky-scan.sh --runs 5 # 指定运行次数 # bash scripts/flaky-scan.sh --spec <文件> # 指定测试文件 # bash scripts/flaky-scan.sh --help # 显示帮助 set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" APP_DIR="${PROJECT_DIR}/everything-is-suitable-uniapp" RUNS=3 SPEC="" VERBOSE=0 # 颜色 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color usage() { echo "Usage: $0 [options]" echo "" echo "Options:" echo " --runs 运行次数 (default: 3)" echo " --spec 指定测试文件" echo " --verbose 详细输出" echo " --help 显示此帮助" exit 0 } while [[ $# -gt 0 ]]; do case "$1" in --runs) RUNS="$2"; shift 2 ;; --spec) SPEC="$2"; shift 2 ;; --verbose) VERBOSE=1; shift ;; --help) usage ;; *) echo "Unknown option: $1"; usage ;; esac done if [ ! -d "$APP_DIR" ]; then echo "错误: 未找到应用目录 ${APP_DIR}" exit 1 fi cd "$APP_DIR" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo " Flaky Test Scanner" echo " 运行次数: ${RUNS}" echo " 测试文件: ${SPEC:-全部}" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" PASS_COUNT=0 FAIL_COUNT=0 declare -a FAILED_RUNS for i in $(seq 1 "$RUNS"); do echo "" echo " [${i}/${RUNS}] 运行中..." if [ -n "$SPEC" ]; then CMD="npx vitest run --reporter=verbose \"$SPEC\"" else CMD="npx vitest run --reporter=verbose" fi if [ "$VERBOSE" -eq 1 ]; then echo " → $CMD" fi set +e OUTPUT=$(eval "$CMD" 2>&1) EXIT_CODE=$? set -e if [ "$EXIT_CODE" -eq 0 ]; then echo -e " [${i}/${RUNS}] ${GREEN}PASS${NC}" PASS_COUNT=$((PASS_COUNT + 1)) else echo -e " [${i}/${RUNS}] ${RED}FAIL${NC} (exit code: ${EXIT_CODE})" FAIL_COUNT=$((FAIL_COUNT + 1)) FAILED_RUNS+=("$i") if [ "$VERBOSE" -eq 1 ]; then echo " --- 失败输出 ---" echo "$OUTPUT" | tail -50 echo " ---" fi fi done echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo " 结果汇总" echo " PASS: ${PASS_COUNT}/${RUNS}" echo " FAIL: ${FAIL_COUNT}/${RUNS}" if [ "$FAIL_COUNT" -eq 0 ]; then echo -e " ${GREEN}结论: 未检测到 flaky 测试,测试稳定 ✓${NC}" exit 0 else echo -e " ${RED}结论: 检测到 flaky 测试${NC}" echo " 失败运行: ${FAILED_RUNS[*]}" echo "" echo " 常见 flaky 根因:" echo " ① vi.clearAllMocks() 不清除 mockResolvedValue 实现" echo " ② 模块级可变 let mock 变量被测试修改未还原" echo " ③ vi.stubGlobal 全局替换未在 afterEach 恢复" echo " ④ waitFor 未 import" echo "" echo " 建议: 对失败运行使用 --verbose 查看详细输出" exit 1 fi